home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / PROGTOOL / LIB211.ZIP;1 / DIALOGS.PRG < prev    next >
Encoding:
Text File  |  1993-11-22  |  233.1 KB  |  5,788 lines

  1. *-----------------------------------------------------------------------
  2. *-- Program...: DIALOGS.PRG
  3. *-- Programmer: Kenneth J. Mayer
  4. *-- Date......: 08/03/1993
  5. *-- Notes.....: This program, which is part of the dUFLP library, 
  6. *--             contains copies of dialog box routines from various 
  7. *--             places in the library. 
  8. *-----------------------------------------------------------------------
  9.  
  10. FUNCTION Message1
  11. *-----------------------------------------------------------------------
  12. *-- Programmer..: Miriam Liskin
  13. *-- Date........: 05/24/1991
  14. *-- Notes.......: Displays a message, centered at whatever line you 
  15. *--               give, pauses until user presses a key.
  16. *-- Written for.: dBASE IV, 1.1
  17. *-- Rev. History: 04/19/1991 Modified by Ken Mayer from Miriam's 
  18. *--                procedure to function
  19. *-- Calls.......: CENTER               Procedure in PROC.PRG
  20. *-- Called by...: Any
  21. *-- Usage.......: message1(<nLine>,<nWidth>,"<cColor>","<cText>")
  22. *-- Example.....: cDummy = Message1(5,12,"RG+/GB","All Done.")
  23. *-- Returns.....: numeric value of key pressed by user (cUser)
  24. *-- Parameters..: nLine  = Line to display message
  25. *--               nWidth = Width of screen
  26. *--               cColor = Colors for display
  27. *--               cText  = Text to be displayed.
  28. *-----------------------------------------------------------------------
  29.  
  30.    parameters nLine,nWidth,cColor,cText
  31.    private cCursor, cUser
  32.    
  33.    @m->nLine,0
  34.    cCursor = set("CURSOR")  && store current state of CURSOR
  35.    set cursor off           && turn it off
  36.    do center with m->nLine,m->nWidth,m->cColor,m->cText
  37.    m->cUser = inkey(0)
  38.    set cursor &cCursor.     && set cursor to original state
  39.    @m->nLine,0              && erase line ...
  40.  
  41. RETURN m->cUser
  42. *-- EoF: Message1()
  43.  
  44. FUNCTION Message2
  45. *-----------------------------------------------------------------------
  46. *-- Programmer..: Miriam Liskin
  47. *-- Date........: 06/08/1992
  48. *-- Notes.......: Displays a message in a window, pauses for user to 
  49. *--               press key
  50. *-- Written for.: dBASE IV, 1.1
  51. *-- Rev. History: 04/19/1991 - Modified by Ken Mayer to a function
  52. *--               04/29/1991 - Modified by Ken Mayer to add shadow
  53. *--               06/08/1992 - Modified by same, to do EXPLICIT setting 
  54. *--                            of colors for window used.
  55. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  56. *--               CENTER               Procedure in PROC.PRG
  57. *-- Called by...: Any
  58. *-- Usage.......: message2("<cText>","<cColor>")
  59. *-- Example.....: cDummy = message2("Finished Processing!",;
  60. *--                         "RG+/GB,,RG+/GB")
  61. *-- Returns.....: numeric value of key pressed by user (cUser)
  62. *-- Parameters..: cText  = Text to be displayed in window
  63. *--               cColor = Colors for window
  64. *-----------------------------------------------------------------------
  65.  
  66.    parameters cText,cColor
  67.    private cCursor, cUser
  68.    
  69.    cCursor = set("CURSOR")
  70.    set cursor off
  71.    save screen to sMessage
  72.    
  73.    *-- NOW we see what happens ...
  74.    activate screen
  75.    define window wMessage from 10,10 to 14,70 double color &cColor.
  76.    do shadow with 10,10,14,70
  77.    activate window wMessage
  78.    
  79.    do center with 1,60,"",m->cText
  80.    wait "" to m->cUser
  81.    
  82.    *-- cleanup
  83.    set cursor &cCursor.
  84.    
  85.    *-- remove window ...
  86.    release window wMessage
  87.    restore screen from sMessage
  88.    release screen sMessage
  89.  
  90. RETURN m->cUser
  91. *-- EoF: Message2()
  92.  
  93. FUNCTION Message3
  94. *-----------------------------------------------------------------------
  95. *-- Programmer..: Miriam Liskin
  96. *-- Date........: 06/08/1992
  97. *-- Notes.......: Displays a message in a window, pauses for user, 
  98. *--               will wrap a long message inside the window.
  99. *-- Written for.: dBASE IV, 1.1
  100. *-- Rev. History: 04/19/1991 - Modified by Ken Mayer to a function
  101. *--               04/29/1991 - Modified to Ken Mayer add shadow
  102. *--               06/08/1992 - Modified to explicitly set the colors ...
  103. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  104. *-- Called by...: Any
  105. *-- Usage.......: Message3("<cText>","<cColor>")
  106. *-- Example.....: cDummy = Message3("This is a long message that will"+;
  107. *--                                 " be wrapped around inside the "+;
  108. *--                                  "window.","rg+/gb,,rg+/gb")
  109. *-- Returns.....: numeric value of key used to exit window (cUser)
  110. *-- Parameters..: cText  = Text to be displayed
  111. *--               cColor = Colors for window
  112. *-----------------------------------------------------------------------
  113.  
  114.    parameters cText,cColor
  115.    private nLines,cCursor,cUser,nLMargin,nRMargin,cAlignment,lWrap
  116.    
  117.    m->nLines = int(len(m->cText) / 38) + 5  && set # of lines for window
  118.    
  119.    cCursor = set("CURSOR")
  120.    set cursor off
  121.    save screen to sMessage
  122.    
  123.    *-- define/activate window
  124.    activate screen
  125.    define window wMessage from 8,20 to 8+m->nLines,60 double ;
  126.                   color &cColor.
  127.    do shadow with 8,20,8+m->nLines,60
  128.    activate window wMessage
  129.    
  130.    m->nLMargin   = _lmargin
  131.    m->nRMargin   = _rmargin
  132.    m->cAlignment = _alignment
  133.    m->lWrap      = _wrap
  134.    
  135.    _lmargin   = 1 
  136.    _rmargin   = 38
  137.    _alignment = "CENTER"
  138.    _wrap      = .t.
  139.    
  140.    ?cText
  141.    ?
  142.    wait "    Press any key to continue . . ." to m->cUser
  143.    
  144.    _lmargin   = m->nLMargin
  145.    _rmargin   = m->nRMargin
  146.    _alignment = m->cAlignment
  147.    _wrap      = m->lWrap
  148.    
  149.    set cursor &cCursor.
  150.    release window wMessage
  151.    restore screen from sMessage
  152.    release screen sMessage
  153.  
  154. RETURN m->cUser
  155. *-- EoF: Message3()
  156.  
  157. FUNCTION Message4
  158. *-----------------------------------------------------------------------
  159. *-- Programmer..: Miriam Liskin
  160. *-- Date........: 11/09/1992
  161. *-- Notes.......: Displays a 2-line message in a predefined window 
  162. *--                 and pauses
  163. *-- Written for.: dBASE IV, 1.1
  164. *-- Rev. History: 04/19/1991 - Modified by Ken Mayer to a function
  165. *--               04/29/1991 - Modified to Ken Mayer add shadow
  166. *--               06/08/1992 -- Modified to explicitly deal with colors
  167. *--               11/09/1992 - Modified by Joey Carroll to deal with 
  168. *--                            text parameters being too long.
  169. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  170. *--               CENTER               Procedure in PROC.PRG
  171. *-- Called by...: Any
  172. *-- Usage.......: message4("<cText1>","<cText2>","<cColor>")
  173. *-- Example.....: cDummy = message4("Finished processing.","There are ";
  174. *--                        +ltrim(str(reccount()))+;
  175. *--                        " Records in this file.",;
  176. *--                        "rg+/rg,rg+/rg,rg+/rg")
  177. *-- Returns.....: numeric value of key pressed by user to exit window 
  178. *--               (cUser)
  179. *-- Parameters..: cText1 = First line of message
  180. *--               cText2 = Second line of message
  181. *--               cColor = Colors for window
  182. *-----------------------------------------------------------------------
  183.  
  184.    parameters cText1,cText2,cColor
  185.    private cCursor,cUser,nLMargin,nRMargin,lWrap
  186.    
  187.    *-- if text params are too long, cut 'em off
  188.    m->cText1 = left(m->cText1,58)
  189.    m->cText2 = left(m->cText2,58)
  190.    
  191.    cCursor = set("CURSOR")
  192.    set cursor off
  193.    save screen to sMessage
  194.    
  195.    activate screen
  196.    define window wMonitor from 10,10 to 17,70 double color &cColor.
  197.    do shadow with 10,10,17,70
  198.    activate window wMonitor
  199.    
  200.    m->nLMargin = _lmargin
  201.    m->nRMargin = _rmargin
  202.    m->lWrap =    _wrap
  203.    _lmargin = 1 
  204.    _rmargin = 58
  205.    _wrap    = .t.
  206.    
  207.    do center with 1,58,"",m->cText1
  208.    do center with 2,58,"",m->cText2
  209.    do center with 4,58,"","Press any key to continue . . ."
  210.    wait "" to m->cUser
  211.  
  212.    _lmargin = m->nLMargin
  213.    _rmargin = m->nRMargin
  214.    _wrap    = m->lWrap
  215.    set cursor &cCursor.
  216.    release window wMonitor
  217.    restore screen from sMessage
  218.    release screen sMessage
  219.    
  220. RETURN m->cUser
  221. *-- EoF: Message4()
  222.  
  223. FUNCTION ScrnHead
  224. *-----------------------------------------------------------------------
  225. *-- Programmer..: Miriam Liskin
  226. *-- Date........: 05/23/1991
  227. *-- Notes.......: Displays a heading on the screen in a box 2 
  228. *--               spaces wider than the text, with a custom border 
  229. *--               (double line top, single the rest)
  230. *-- Written for.: dBASE IV, 1.1
  231. *-- Rev. History: 4/29/1991 - Modified by Ken Mayer to add shadow
  232. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  233. *-- Called by...: Any
  234. *-- Usage.......: scrnhead("<cColor>","<cText>")
  235. *-- Examples....: cDummy = ScrnHead("rg+/gb","Print Financial Report")
  236. *-- Returns.....: nul/""
  237. *-- Parameters..: cColor = Colors to display box/text in
  238. *--               cText  = text to be displayed.
  239. *-----------------------------------------------------------------------
  240.  
  241.    parameters cColor,cText
  242.    private cTextStart,cText2
  243.    
  244.    m->cText2 = " "+trim(m->cText)+" "     && ad spaces to left and right
  245.    m->cTextstart = (80-len(trim(m->cText2)))/2
  246.    activate screen
  247.    do shadow with 1,m->cTextstart-1,3,81-m->cTextstart
  248.    @1,m->cTextstart-1 to 3,81-m->cTextstart ;
  249.            205,196,179,179,213,184,192,217 color &cColor. && display box
  250.    @2, m->cTextstart say m->cText2 color &cColor.        && display text
  251.  
  252. RETURN ""
  253. *-- EoF: ScrnHead()
  254.  
  255. FUNCTION ScrnHead2
  256. *-----------------------------------------------------------------------
  257. *-- Programmer..: Miriam Liskin
  258. *-- Date........: 03/17/1993
  259. *-- Notes.......: Displays a heading on the screen in a box 2 
  260. *--               spaces wider than the text, with a 3-d border.
  261. *--               WARNING: This dialog box is two rows taller and two 
  262. *--               columns wider than previous versions. For the purposes
  263. *--               of screen control, I moved this up to row 0 on the 
  264. *--               screen (you may need to SET SCOREBOARD OFF), and 
  265. *--               down one further row, so all screen changes should 
  266. *--               start at row 6, or you will destroy the shadow ... 
  267. *--               (it's only one extra row, but it will make a 
  268. *--               difference)
  269. *-- Written for.: dBASE IV, 1.5
  270. *-- Rev. History: 04/29/1991 - Modified by Ken Mayer to add shadow
  271. *--               03/17/1993 -- Changed to give 3-D Border
  272. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  273. *--               BORD3D2              Procedure in PROC.PRG
  274. *-- Called by...: Any
  275. *-- Usage.......: scrnhead2("<cColor>","<cText>"[,<nStyle>])
  276. *-- Examples....: cDummy=ScrnHead2("rg+/gb","Print Financial Report",1)
  277. *-- Returns.....: nul/""
  278. *-- Parameters..: cColor = Colors to display box/text in
  279. *--               cText  = text to be displayed.
  280. *--               nStyle = Type of 3-d Border (passed directly to 
  281. *--                        procedure)
  282. *--                        1 = raised, 2 = inset
  283. *-----------------------------------------------------------------------
  284.  
  285.    parameters cColor,cText, nStyle
  286.    private nTextStart,cText2
  287.    
  288.    *-- if style parameter not passed, use default
  289.    if pCount() < 3
  290.       m->nStyle = 1
  291.    endif
  292.    
  293.    *-- deal with border -- save old setting, set to single
  294.    cBorder = set("BORDER")
  295.    set border to single
  296.    
  297.    m->cText2 = " "+trim(m->cText)+" "     && ad spaces to left and right
  298.    m->nTextStart = (81-len(trim(m->cText2)))/2  
  299.                                           && centered text on screen
  300.    activate screen
  301.    m->nTop    = 0
  302.    m->nLeft   = m->nTextStart - 3      && back up 3
  303.    m->nBottom = 4                      && bottom row
  304.    m->nRight  = (81-m->nTextStart) + 3 && right 3
  305.    
  306.    *-- draw shadow
  307.    do shadow with m->nTop,m->nLeft,m->nBottom,m->nRight
  308.    
  309.    *-- fill in box
  310.    @m->nTop,m->nLeft fill to m->nBottom,m->nRight color &cColor.
  311.    
  312.    *-- place border on top of it all
  313.    do bord3d2 with m->nTop,m->nLeft,m->nBottom,m->nRight,;
  314.                    m->cColor,m->nStyle
  315.    
  316.    *-- finally, let's display the text ...
  317.    @2, m->nTextStart say m->cText2 color &cColor. && display text
  318.  
  319. RETURN ""
  320. *-- EoF: ScrnHead2()
  321.  
  322. FUNCTION ScrnHead3
  323. *-----------------------------------------------------------------------
  324. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  325. *-- Date........: 06/09/1993
  326. *-- Notes.......: Displays a heading on the screen in a box 2 
  327. *--               spaces wider than the text. This comes with a three-d
  328. *--               border.
  329. *--               NOTE: This routine is based on the work of Miriam 
  330. *--               Liskin, and my own modifications over the years.
  331. *-- Written for.: dBASE IV, 1.5
  332. *-- Rev. History: 06/09/1993 -- Original
  333. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  334. *--               BORD3D5              Procedure in DIALOGS.PRG
  335. *-- Called by...: Any
  336. *-- Usage.......: scrnhead3("<cColor>","<cText>"[,<nStyle>])
  337. *-- Examples....: cDummy =ScrnHead3("rg+/gb","Print Financial Report",1)
  338. *-- Returns.....: nul/""
  339. *-- Parameters..: cColor = Colors to display box/text in
  340. *--                        Default to grey
  341. *--               cText  = text to be displayed.
  342. *--               nStyle = Type of 3-d Border (passed directly to 
  343. *--                        procedure)
  344. *--                        1 = double - raised   (Default)
  345. *--                        2 = double - recessed
  346. *--                        3 = single - raised
  347. *--                        4 = single - recessed
  348. *-----------------------------------------------------------------------
  349.  
  350.    parameters cColor,cText, nStyle
  351.    private nTextStart,cText2
  352.    
  353.    *-- if style parameter not passed, use default
  354.    if pCount() < 3 .or. (m->nStyle < 1 .or. m->nStyle > 4)
  355.       m->nStyle = 1
  356.    endif
  357.    
  358.    *-- colors
  359.    if isblank(m->cColor)
  360.       m->cColor = "n/w"
  361.    endif
  362.    
  363.    m->cText2 = " "+trim(m->cText)+" "     && ad spaces to left and right
  364.    m->nTextStart = (81-len(trim(m->cText2)))/2    
  365.                                           && centered text on screen
  366.    activate screen
  367.    m->nTop    = iif(m->nStyle < 3,0,1)
  368.    m->nLeft   = m->nTextStart - iif(m->nStyle<3,3,2)
  369.                                           && back up 3 (or 2)
  370.    m->nBottom = iif(m->nStyle < 3,4,3)    && bottom row
  371.    m->nRight  = (81-m->nTextStart) + iif(m->nStyle<3,3,2)  
  372.                                           && right 3 (or 2)
  373.    
  374.    *-- draw shadow
  375.    do shadow with m->nTop,m->nLeft,m->nBottom,m->nRight
  376.    
  377.    *-- fill in box
  378.    @m->nTop,m->nLeft fill to m->nBottom,m->nRight color &cColor.
  379.    
  380.    *-- place border on top of it all
  381.    do bord3d5 with m->nTop,m->nLeft,m->nBottom,m->nRight,;
  382.                                     m->cColor,m->nStyle
  383.    
  384.    *-- finally, let's display the text ...
  385.    @2, m->nTextStart say m->cText2 color &cColor. && display text
  386.  
  387. RETURN ""
  388. *-- EoF: ScrnHead3()
  389.  
  390. FUNCTION YesNo
  391. *-----------------------------------------------------------------------
  392. *-- Programmer..: Miriam Liskin
  393. *-- Date........: 06/08/1992
  394. *-- Notes.......: Asks a yes/no question in a dialog window/box
  395. *-- Written for.: dBASE IV, 1.1
  396. *-- Rev. History: 04/19/1991 - Modified by Ken Mayer to become a 
  397. *--                            function
  398. *--               04/29/1991 - Modified by Ken Mayer add shadow
  399. *--               05/13/1991 - Modified by Ken Mayer remove need for 
  400. *--                            extra procedures (YES/NO) that were used
  401. *--                            for returning values from Menu
  402. *--                            (suggested by Clinton L. Warren (VBCES))
  403. *--               01/20/1992 - Modified by Martin Leon (HMan) to handle
  404. *--                            user pressing 'Y' or 'N' keys (with ON 
  405. *--                            KEY ...).
  406. *--               04/22/1992 - Modified by Ken Mayer adding CLEAR 
  407. *--                            TYPEAHEAD, as occaisional problems appear
  408. *--                            otherwise.
  409. *--               06/08/1992 - Modified (Ken Mayer) to deal with 
  410. *--                            explicit color processing.
  411. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  412. *--               CENTER               Procedure in PROC.PRG
  413. *-- Called by...: Any
  414. *-- Usage.......: yesno(<lAnswer>,"<cMess1>","<cMess2>","<cMess3>",;
  415. *--                    "<cColor>")
  416. *-- Example.....: if YesNo(.t.,"Do You Really Wish To Delete?",;
  417. *--                            "This will destroy the data";
  418. *--                             "in this record.";
  419. *--                             "rg+/gb,n/w,rg+/gb")
  420. *--                  delete
  421. *--               else
  422. *--                  skip
  423. *--               endif
  424. *--
  425. *--                 The middle set of colors should be different, as 
  426. *--                 they will be the colors of the YES/NO selections ...
  427. *--                 Options may be blank by using nul values ("")
  428. *-- Returns.....: .t./.f. depending on user's choice from menu
  429. *-- Parameters..: lAnswer = default value (Yes or No) for menu
  430. *--               cMess1  =  First line of Message
  431. *--               cMess2  =  Second line of message
  432. *--               cMess3  =  Third line of message
  433. *--               cColor  =  Colors for window/menu/box
  434. *-----------------------------------------------------------------------
  435.  
  436.    parameter lAnswer,cMess1,cMess2,cMess3,cColor
  437.    
  438.    save screen to sYesno
  439.    activate screen
  440.    define window wYesno from 8,20 to 15,60 double color &cColor.
  441.    
  442.    define menu mYesno
  443.    *-- remove && from MESSAGE option if using or might be used on 
  444.    *-- Mono system
  445.    define pad pYes of mYesno Prompt "[Yes]" at 5,10 && message "Yes"
  446.    define pad pNo  of mYesno Prompt "[No]"  at 5,25 && message "No"
  447.    on selection pad pYes of mYesno deactivate menu
  448.    on selection pad pNo  of mYesno deactivate menu
  449.    
  450.    do shadow with 8,20,15,60
  451.    activate window wYesno
  452.    
  453.    do center with 0,38,"",m->cMess1           && center the text
  454.    do center with 2,38,"",m->cMess2
  455.    do center with 3,38,"",m->cMess3
  456.  
  457.    *-- deal with user pressing 'Y' or 'N' ...
  458.    on key label Y keyboard IIF( PAD() = "PYES", "", CHR(19) )+chr(13)
  459.    on key label N keyboard IIF( PAD() = "PNO",  "", CHR(4)  )+chr(13)
  460.  
  461.    *-- otherwise deal with regular "menu" abilities
  462.    clear typeahead
  463.    if m->lAnswer
  464.       activate menu mYesno pad pYes
  465.    else
  466.       activate menu mYesno pad pNo
  467.    endif
  468.    
  469.    *-- clear out ON KEY settings ...
  470.    on key label Y
  471.    on key label N
  472.    release window wYesno
  473.    restore screen from sYesno
  474.    release screen sYesno
  475.    release menu mYesno
  476.  
  477. RETURN iif(pad()="PYES",.t.,.f.)
  478. *-- EoF: YesNo()
  479.  
  480. FUNCTION YesNo2
  481. *-----------------------------------------------------------------------
  482. *-- Programmer..: Miriam Liskin
  483. *-- Date........: 06/08/1992
  484. *-- Notes.......: Asks a yes/no question in a dialog window/box
  485. *-- Written for.: dBASE IV, 1.1
  486. *-- Rev. History: 04/19/1991 - Modified by Ken Mayer to become a 
  487. *--                            function
  488. *--               04/29/1991 - Modified by Ken Mayer add shadow
  489. *--               05/13/1991 - Modified by Ken Mayer remove need for 
  490. *--                            extra procedures (YES/NO) that were used 
  491. *--                            for returning values from Menu
  492. *--                            (suggested by Clinton L. Warren (VBCES))
  493. *--               11/15/1991 - Copied YesNo, modified to allow 
  494. *--                            "location" options -- useful for some
  495. *--                            screens ...
  496. *--               01/20/1992 - Modified by Martin Leon (HMAN) to allow
  497. *--                            user to press 'Y' or 'N' and have them
  498. *--                            recognized ...
  499. *--               04/22/1992 - Modified by Ken Mayer adding CLEAR 
  500. *--                            TYPEAHEAD, as occaisional problems appear
  501. *--                            otherwise.
  502. *--               06/08/1992 - Modified by same for explicit color sets.
  503. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  504. *--               CENTER               Procedure in PROC.PRG
  505. *-- Called by...: Any
  506. *-- Usage.......: yesno2(<lAnswer>,"<cWhere>",;
  507. *--                                "<cMess1>","<cMess2>","<cMess3>",;
  508. *--                                "<cColor>")
  509. *-- Example.....: if YesNo2(.t.,"UL","Do You Really Wish To Delete?",;
  510. *--                            "This will destroy the data";
  511. *--                             "in this record.";
  512. *--                             "rg+/gb,n/w,rg+/gb")
  513. *--                  delete
  514. *--               else
  515. *--                  skip
  516. *--               endif
  517. *--
  518. *--                 The middle set of colors should be different, as 
  519. *--                 they will be the colors of the YES/NO selections ...
  520. *--                 Options may be blank by using nul values ("")
  521. *-- Returns.....: .t./.f. depending on user's choice from menu
  522. *-- Parameters..: lAnswer = default value (Yes or No) for menu
  523. *--               cWhere  = location on screen:
  524. *--                            "UL" = Upper Left
  525. *--                            "UC" = Upper Center
  526. *--                            "UR" = Upper Right
  527. *--                            "CL" = Center Left
  528. *--                            "CC" = Center Center
  529. *--                            "CR" = Center Right
  530. *--                            "BL" = Bottom Left
  531. *--                            "BC" = Bottom Center
  532. *--                            "BR" = Bottom Right
  533. *--               cMess1  =  First line of Message
  534. *--               cMess2  =  Second line of message (may be nul = "")
  535. *--               cMess3  =  Third line of message  (may be nul = "")
  536. *--               cColor  =  Colors for window/menu/box
  537. *-----------------------------------------------------------------------
  538.  
  539.    parameter lAnswer,cWhere,cMess1,cMess2,cMess3,cColor
  540.    private cExact,cW1,cW2,nULB,nBRR,nULC,nBRC
  541.       
  542.    cExact = set("EXACT")
  543.    save screen to sYesno
  544.    
  545.    *-- see what the user gave us ...
  546.    if len(trim(m->cWhere)) > 0
  547.       m->cW1 = upper(left(m->cWhere,1))  && first coordinate (vertical)
  548.       m->cW2 = upper(right(m->cWhere,1)) && second coordinate (horiz.)
  549.    else
  550.       m->cW1 = "C"
  551.       m->cW2 = "C"
  552.    endif
  553.    *-- deal with vertical placement
  554.    do case
  555.       case m->cW1 = "U"
  556.          m->nULR =  1   && upper left row
  557.          m->nBRR =  8   && bottom right row
  558.       case m->cW1 = "C"
  559.          m->nULR =  8
  560.          m->nBRR = 15
  561.       case m->cW1 = "B"
  562.          m->nULR = 15
  563.          m->nBRR = 22
  564.    endcase
  565.    *-- deal with horizontal placement
  566.    do case
  567.       case m->cW2 = "L"
  568.          m->nULC =  5   && upper left column
  569.          m->nBRC = 45   && bottom right column
  570.       case m->cW2 = "R"
  571.          m->nULC = 35
  572.          m->nBRC = 75
  573.       case m->cW2 = "C"
  574.          m->nULC = 20
  575.          m->nBRC = 60
  576.    endcase
  577.    
  578.    activate screen
  579.    define window wYesno from m->nULR,m->nULC to m->nBRR,m->nBRC;
  580.                         double color &cColor.
  581.    
  582.    define menu mYesno
  583.    *-- remove && from MESSAGE option if using or might be used on 
  584.    *-- Mono system
  585.    define pad pYes of mYesno Prompt "[Yes]" at 5,10 && message "Yes"
  586.    define pad pNo  of mYesno Prompt "[No]"  at 5,25 && message "No"
  587.    on selection pad pYes of mYesno deactivate menu
  588.    on selection pad pNo  of mYesno deactivate menu
  589.    *-- start displaying it ... shadow, window ...
  590.    do shadow with m->nULR,m->nULC,m->nBRR,m->nBRC
  591.    activate window wYesno
  592.    
  593.    *-- display text
  594.    do center with 0,38,"",m->cMess1           && center the text
  595.    do center with 2,38,"",m->cMess2
  596.    do center with 3,38,"",m->cMess3
  597.    *-- set 'y' or 'n' keys ...
  598.    on key label Y keyboard IIF( PAD() = "PYES", "", CHR(19) )+chr(13)
  599.    on key label N keyboard IIF( PAD() = "PNO",  "", CHR(4)  )+chr(13)
  600.    clear typeahead
  601.    if m->lAnswer
  602.       activate menu mYesno pad pYes
  603.    else
  604.       activate menu mYesno pad pNo
  605.    endif
  606.    
  607.    *-- reset system ...
  608.    on key label Y
  609.    on key label N
  610.    release window wYesno
  611.    restore screen from sYesno
  612.    release screen sYesno
  613.    release menu mYesno
  614.    set exact &cExact
  615.    
  616. RETURN iif(pad()="PYES",.t.,.f.)
  617. *-- EoF: YesNo2()
  618.  
  619. FUNCTION YesNo3
  620. *-----------------------------------------------------------------------
  621. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  622. *-- Date........: 01/06/1993
  623. *-- Notes.......: A version of the YESNO() routines in PROC.PRG, that 
  624. *--               will handle a long (up to 254 character) message 
  625. *--               string, is centered on the screen, and has a title 
  626. *--               bar kind of like a Windows dialog box ...
  627. *-- Written for.: dBASE IV, 1.5
  628. *-- Rev. History: 01/06/1993 -- Original
  629. *-- Calls.......: Center               Procedure in PROC.PRG
  630. *--               Shadow               Procedure in PROC.PRG
  631. *--               WordWrap             Procedure in STRINGS.PRG
  632. *--               ColorBrk()           Function in PROC.PRG
  633. *--               FBClrBrk()           Function in PROC.PRG
  634. *--               Justify()            Function in PROC.PRG
  635. *-- Called by...: Any
  636. *-- Usage.......: YesNo3(<lDefault>,<cTitle>,<cMessage>,<cColor>)
  637. *-- Example.....: if YesNo3(.t.,"Test","This is a message of any "+;
  638. *--                         "length up to 254 characters.",cWind1)
  639. *-- Returns.....: logical
  640. *-- Parameters..: lDefault  = Logical value, for the default menu pad 
  641. *--                           (Yes/No)
  642. *--               cTitle    = Title for title bar -- no longer than 30 
  643. *--                           characters.
  644. *--               cMessage  = Message - up to 254 characters in length.
  645. *--               cColor    = "Standard" colors for window/menu/box
  646. *-----------------------------------------------------------------------
  647.  
  648.    parameters lDefault, cTitle, cMessage, cColor
  649.    private nULRow, nULCol, nBRRow, nBRCol
  650.    
  651.    *-- save it, so we can activate the screen and display a window on 
  652.    *-- top of whatever's there
  653.    save screen to sYesNo
  654.    
  655.    *-- save window if there is one, and activate screen to be safe:
  656.    wWindow = window()
  657.    activate screen
  658.    
  659.    *-- now to define the coordinates ...
  660.    m->nULCol = 20   && left side of box
  661.    m->nBRCol = 60   && right side of box
  662.    
  663.    m->nWidth =  36  && width of dialog box ... 36 characters for text
  664.    m->nHeight = int(len(m->cMessage)/m->nWidth)
  665.    *-- if the remainder of the length of the message/width of box is > 0
  666.    *-- we have one more line of text ...
  667.    m->nHeight = m->nHeight + iif(mod(len(m->cMessage),m->nWidth)>0,1,0)
  668.    
  669.    *-- deal with room for title, and menu at bottom
  670.    m->nHeight = m->nHeight + 4
  671.    
  672.    *-- row coordinates
  673.    m->nULRow = (24-m->nHeight) / 2     && top row
  674.    m->nBRRow = m->nULRow + m->nHeight + 1
  675.    
  676.    *-- define the window
  677.    define window wYesNo from m->nULRow,m->nULCol to m->nBRRow,m->nBRCol;
  678.                                                 double color &cColor.
  679.    
  680.    *-- now for the menu pads
  681.    define menu mYesNo
  682.    define pad pYes of mYesNo prompt "[Yes]" at m->nHeight - 1,10
  683.    define pad pNo  of mYesNo prompt "[No]"  at m->nHeight - 1,25
  684.    on selection pad pYes of mYesNo deactivate menu
  685.    on selection pad pNo  of mYesNo deactivate menu
  686.    
  687.    *-- display it
  688.    do shadow with m->nULRow,m->nULCol,m->nBRRow,m->nBRCol
  689.    activate window wYesNo
  690.    
  691.    *-- display title
  692.    if len(cTitle) < m->nWidth
  693.       m->cTitle = justify(m->cTitle,39,"C")
  694.       if len(m->cTitle) < 39
  695.          m->cTitle = m->cTitle + " "
  696.       endif
  697.    endif
  698.    m->cTempCol = colorbrk(m->cColor,2)
  699.    m->cColorF  = FBClrBrk("B",m->cTempCol)
  700.    m->cColorB  = FBClrBrk("B",colorbrk(m->cColor,1))
  701.    m->cColorAll = m->cColorF + "/" + m->cColorB
  702.    @0,0 say m->cTitle color &cTempCol.
  703.    @1,0 say replicate(chr(223),39) color &cColorAll.
  704.    
  705.    *-- display message
  706.    do WordWrap with 2,2,m->cMessage,35
  707.    
  708.    *-- set Y/N keys for menu pad
  709.    clear typeahead && just to be safe
  710.    on key label Y keyboard iif(pad() = "PYES","",chr(19))+chr(13)
  711.    on key label N keyboard iif(pad() = "PNO", "",chr(4) )+chr(13)
  712.    
  713.    *-- activate the menu
  714.    if m->lDefault
  715.       activate menu mYesNo pad pYes
  716.    else
  717.       activate menu mYesNo pad pNo
  718.    endif
  719.    
  720.    *-- reset system
  721.    on key label Y
  722.    on key label N
  723.    release window wYesNo
  724.    restore screen from sYesNo
  725.    release screen sYesNo
  726.    release menu mYesNo
  727.    if .not. isblank(m->wWindow)
  728.       activate window &wWindow.
  729.    endif
  730.  
  731. RETURN iif(pad() = "PYES",.t.,.f.)
  732. *-- EoF: YesNo3()
  733.  
  734. FUNCTION YesNo4
  735. *-----------------------------------------------------------------------
  736. *-- Programmer..: Miriam Liskin
  737. *-- Date........: 03/15/1993
  738. *-- Notes.......: Asks a yes/no question in a dialog window/box
  739. *--               Made to look 3-D, removed COLOR parameter, so we could
  740. *--               do this with Borland's STEEL GREY look ... (and it 
  741. *--               works with other colors ...)
  742. *--               WARNING: If it matters to you -- this dialog box is 2
  743. *--               columns wider, and two rows taller than previous 
  744. *--               versions.
  745. *-- Written for.: dBASE IV, 1.5
  746. *-- Rev. History: 04/19/1991 - Modified by Ken Mayer to become a 
  747. *--                            function
  748. *--               04/29/1991 - Modified by Ken Mayer add shadow
  749. *--               05/13/1991 - Modified by Ken Mayer remove need for 
  750. *--                            extra procedures (YES/NO) that were 
  751. *--                            used for returning values from Menu
  752. *--                            (suggested by Clinton L. Warren (VBCES))
  753. *--               11/15/1991 - Copied YesNo, modified to allow 
  754. *--                            "location" options -- useful for some 
  755. *--                            screens ...
  756. *--               01/20/1992 - Modified by Martin Leon (HMAN) to allow 
  757. *--                            user to press 'Y' or 'N' and have them 
  758. *--                            recognized ...
  759. *--               04/22/1992 - Modified by Ken Mayer adding CLEAR 
  760. *--                            TYPEAHEAD, as occaisional problems appear
  761. *--                            otherwise.
  762. *--               06/08/1992 - Modified by same for explicit color sets.
  763. *--               03/15/1993 - Modified to look 3-D by playing with 
  764. *--                            borders.
  765. *--                            (I got the idea from the Compiler flier)
  766. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  767. *--               CENTER               Procedure in PROC.PRG
  768. *--               BORD3D               Procedure in PROC.PRG
  769. *-- Called by...: Any
  770. *-- Usage.......: YesNo4(<lAnswer>,"<cWhere>",;
  771. *--                                "<cMess1>","<cMess2>","<cMess3>",;
  772. *--                                <cColor> [,<nStyle>])
  773. *-- Example.....: if YesNo4(.t.,"UL","Do You Really Wish To Delete?",;
  774. *--                            "This will destroy the data";
  775. *--                            "in this record.","rg+/gb,w+/n,rg+/gb",1)
  776. *--                  delete
  777. *--               else
  778. *--                  skip
  779. *--               endif
  780. *--
  781. *--                 The middle set of colors should be different, as 
  782. *--                 they will be the colors of the YES/NO selections 
  783. *--                 Options may be blank by using nul values ("")
  784. *-- Returns.....: .t./.f. depending on user's choice from menu
  785. *-- Parameters..: lAnswer  = default value (Yes or No) for menu
  786. *--               cWhere   = location on screen:
  787. *--                             "UL" = Upper Left
  788. *--                             "UC" = Upper Center
  789. *--                             "UR" = Upper Right
  790. *--                             "CL" = Center Left
  791. *--                             "CC" = Center Center
  792. *--                             "CR" = Center Right
  793. *--                             "BL" = Bottom Left
  794. *--                             "BC" = Bottom Center
  795. *--                             "BR" = Bottom Right
  796. *--               cMess1   =  First line of Message
  797. *--               cMess2   =  Second line of message (may be nul = "")
  798. *--               cMess3   =  Third line of message  (may be nul = "")
  799. *--               cColor   =  Colors: forg/back,forg/back,forg/back
  800. *--                           where the first set is window/text color,
  801. *--                           next is highlighted pad color,
  802. *--                           last is border color
  803. *--               nStyle   =  Optional -- 1 = raised 3-d Border,
  804. *--                                       2 = inset 3-d Border
  805. *--                     (Note that this is passed directly to BORD3D)
  806. *-----------------------------------------------------------------------
  807.  
  808.    parameter lAnswer,cWhere,cMess1,cMess2,cMess3,cColor,nStyle
  809.    private cExact,cW1,cW2,nULB,nBRR,nULC,nBRC
  810.       
  811.    cExact = set("EXACT")
  812.    cWindow = window()     && save "window" name if there is one active
  813.    save screen to sYesno
  814.    
  815.    *-- see what the user gave us ...
  816.    if len(trim(m->cWhere)) > 0
  817.       m->cW1 = upper(left(m->cWhere,1))  && first coordinate (vertical)
  818.       m->cW2 = upper(right(m->cWhere,1)) && second coordinate (horiz.)
  819.    else
  820.       m->cW1 = "C"
  821.       m->cW2 = "C"
  822.    endif
  823.    *-- deal with vertical placement
  824.    do case
  825.       case m->cW1 = "U"
  826.          m->nULR =  1   && upper left row
  827.          m->nBRR =  10   && bottom right row
  828.       case m->cW1 = "C"
  829.          m->nULR =  7
  830.          m->nBRR = 16
  831.       case m->cW1 = "B"
  832.          m->nULR = 13
  833.          m->nBRR = 22
  834.    endcase
  835.    *-- deal with horizontal placement
  836.    do case
  837.       case m->cW2 = "L"
  838.          m->nULC =  5   && upper left column
  839.          m->nBRC = 45   && bottom right column
  840.       case m->cW2 = "R"
  841.          m->nULC = 35
  842.          m->nBRC = 75
  843.       case m->cW2 = "C"
  844.          m->nULC = 20
  845.          m->nBRC = 60
  846.    endcase
  847.    
  848.    activate screen
  849.    define window wYesno from m->nULR,m->nULC to m->nBRR,m->nBRC;
  850.                                               NONE color &cColor.
  851.    
  852.    define menu mYesno
  853.    define pad pYes of mYesno Prompt "[Yes]" at 7,12 
  854.    define pad pNo  of mYesno Prompt "[No]"  at 7,27 
  855.    on selection pad pYes of mYesno deactivate menu
  856.    on selection pad pNo  of mYesno deactivate menu
  857.    
  858.    *-- start displaying it ... shadow, window ...
  859.    do shadow with m->nULR,m->nULC,m->nBRR,m->nBRC
  860.    activate window wYesno
  861.    
  862.    *-- do 3d border ...
  863.    if pCount() < 7     && if optional parm not passed, set default
  864.       m->nStyle = 1    &&   which is the 'raised' border
  865.    endif
  866.    do bord3d with 9,40,m->cColor,m->nStyle
  867.    
  868.    *-- display text
  869.    do center with 2,40,"",left(m->cMess1,34)   && center the text
  870.    do center with 4,40,"",left(m->cMess2,34)
  871.    do center with 5,40,"",left(m->cMess3,34)
  872.    *-- set 'y' or 'n' keys ...
  873.    on key label Y keyboard IIF( PAD() = "PYES", "", CHR(19) )+chr(13)
  874.    on key label N keyboard IIF( PAD() = "PNO",  "", CHR(4)  )+chr(13)
  875.    clear typeahead
  876.    if m->lAnswer
  877.       activate menu mYesno pad pYes
  878.    else
  879.       activate menu mYesno pad pNo
  880.    endif
  881.    
  882.    *-- reset system ...
  883.    on key label Y
  884.    on key label N
  885.    release window wYesno
  886.    restore screen from sYesno
  887.    release screen sYesno
  888.    release menu mYesno
  889.    if .not. isblank(cWindow)
  890.       activate window &cWindow.
  891.    endif
  892.    set exact &cExact.
  893.    
  894. RETURN iif(pad()="PYES",.t.,.f.)
  895. *-- EoF: YesNo4()
  896.  
  897. FUNCTION YesNo5
  898. *-----------------------------------------------------------------------
  899. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  900. *-- Date........: 03/16/1993
  901. *-- Notes.......: A version of the YESNO() routines in DIALOGS.PRG, 
  902. *--               that will handle a long (up to 254 character) message 
  903. *--               string, is centered on the screen, and has a title 
  904. *--               bar kind of like a Windows dialog box ... (This 
  905. *--               version is a modification YESNO3() with a "3-D Border"
  906. *--               added to it ...)
  907. *--               WARNING: This dialog box is two rows taller and two 
  908. *--               columns wider than previous versions.
  909. *-- Written for.: dBASE IV, 1.5
  910. *-- Rev. History: 01/06/1993 -- Original
  911. *--               03/16/1993 -- Added 3-D border
  912. *-- Calls.......: Center               Procedure in PROC.PRG
  913. *--               Shadow               Procedure in PROC.PRG
  914. *--               WordWrap             Procedure in STRINGS.PRG
  915. *--               ColorBrk()           Function in PROC.PRG
  916. *--               FBClrBrk()           Function in PROC.PRG
  917. *--               Justify()            Function in PROC.PRG
  918. *--               Bord3D               Procedure in PROC.PRG
  919. *-- Called by...: Any
  920. *-- Usage.......: YesNo5(<lDefault>,<cTitle>,<cMessage>,<cColor>;
  921. *--                      [,<nStyle>])
  922. *-- Example.....: if YesNo5(.t.,"Test","This is a message of any "+;
  923. *--                             "length up to 254 characters.",cWind1,2)
  924. *-- Returns.....: logical
  925. *-- Parameters..: lDefault  = Logical value, for the default menu pad 
  926. *--                           (Yes/No)
  927. *--               cTitle    = Title for title bar -- no longer than 30 
  928. *--                           characters.
  929. *--               cMessage  = Message - up to 254 characters in length.
  930. *--               cColor    = "Standard" colors for window/menu/box
  931. *--               nStyle    = Optional: nStyle = 1 means raised border
  932. *--                                     nStyle = 2 means inset border
  933. *----------------------------------------------------------------------
  934.  
  935.    parameters lDefault, cTitle, cMessage, cColor, nStyle
  936.    private nULRow, nULCol, nBRRow, nBRCol, m->nLMargin, nRMargin, lWrap
  937.    
  938.    if pCount() < 5
  939.       m->nStyle = 1
  940.    endif
  941.    
  942.    *-- save it, so we can activate the screen and display a window on 
  943.    *-- top of whatever's there
  944.    save screen to sYesNo
  945.    
  946.    *-- save window if there is one, and activate screen to be safe:
  947.    wWindow = window()
  948.    activate screen
  949.    
  950.    *-- now to define the coordinates ...
  951.    m->nULCol = 20   && left side of box
  952.    m->nBRCol = 60   && right side of box
  953.    
  954.    m->nWidth =  36  && width of dialog box ... 36 characters for text
  955.    m->nHeight = int(len(m->cMessage)/m->nWidth)
  956.    *-- if the remainder of the length of the message/width of box is > 0
  957.    *-- we have one more line of text ...
  958.    m->nHeight = m->nHeight + iif(mod(len(m->cMessage),m->nWidth)>0,1,0)  
  959.    
  960.    *-- deal with room for title, and menu at bottom (and 3-D Border)
  961.    m->nHeight = m->nHeight + 8
  962.    
  963.    *-- row coordinates
  964.    m->nULRow = (24-m->nHeight) / 2     && top row
  965.    m->nBRRow = m->nULRow + m->nHeight
  966.    
  967.    *-- define the window
  968.    define window wYesNo from m->nULRow,m->nULCol to m->nBRRow,m->nBRCol;
  969.                                   NONE color &cColor.
  970.    
  971.    *-- now for the menu pads
  972.    define menu mYesNo
  973.    define pad pYes of mYesNo prompt "[Yes]" at m->nHeight - 2,10
  974.    define pad pNo  of mYesNo prompt "[No]"  at m->nHeight - 2,25
  975.    on selection pad pYes of mYesNo deactivate menu
  976.    on selection pad pNo  of mYesNo deactivate menu
  977.    
  978.    *-- display it
  979.    do shadow with m->nULRow,m->nULCol,m->nBRRow,m->nBRCol
  980.    activate window wYesNo
  981.    
  982.    *-- put 3-D border on it
  983.    do Bord3D with m->nHeight,m->nWidth+4,m->cColor,m->nStyle
  984.    
  985.    *-- display title
  986.    if len(m->cTitle) < m->nWidth
  987.       m->cTitle = justify(m->cTitle,35,"C")
  988.       if len(m->cTitle) < 35
  989.          m->cTitle = m->cTitle + " "
  990.       endif
  991.    endif
  992.    m->cTempCol = colorbrk(m->cColor,2)
  993.    m->cColorF  = FBClrBrk("B",cTempCol)
  994.    m->cColorB  = FBClrBrk("B",colorbrk(m->cColor,1))
  995.    m->cColorAll = m->cColorF + "/" + m->cColorB
  996.    @2,3 say m->cTitle color &cTempCol.
  997.    @3,3 say replicate(chr(223),35) color &cColorAll.
  998.    
  999.    *-- display message
  1000.    do WordWrap with 4,4,m->cMessage,34
  1001.    
  1002.    *-- set Y/N keys for menu pad
  1003.    clear typeahead && just to be safe
  1004.    on key label Y keyboard iif(pad() = "PYES","",chr(19))+chr(13)
  1005.    on key label N keyboard iif(pad() = "PNO", "",chr(4) )+chr(13)
  1006.    
  1007.    *-- activate the menu
  1008.    if m->lDefault
  1009.       activate menu mYesNo pad pYes
  1010.    else
  1011.       activate menu mYesNo pad pNo
  1012.    endif
  1013.    
  1014.    *-- reset system
  1015.    on key label Y
  1016.    on key label N
  1017.    deactivate window wYesNo
  1018.    release window wYesNo
  1019.    restore screen from sYesNo
  1020.    release screen sYesNo
  1021.    release menu mYesNo
  1022.    if .not. isblank(m->wWindow)
  1023.       activate window &wWindow.
  1024.    endif
  1025.  
  1026. RETURN iif(pad() = "PYES",.t.,.f.)
  1027. *-- EoF: YesNo5()
  1028.  
  1029. FUNCTION YesNo6
  1030. *-----------------------------------------------------------------------
  1031. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  1032. *-- Date........: 06/11/1993
  1033. *-- Notes.......: This is a combination of the "best" of YESNO4() and
  1034. *--               YESNO5() (I hope). The work involved is based on work
  1035. *--               by Miriam Liskin, Martin Leon, Clinton Warren,
  1036. *--               Joey D. Carol, and myself. 
  1037. *--               This Yes/No dialog box should do the following:
  1038. *--               A) Full 3-D effect(s)
  1039. *--               B) Color options up to programmer/user
  1040. *--               C) YES/NO buttons at bottom of dialog box
  1041. *--               D) Allow for location on screen
  1042. *--               E) Allow for up to 256 characters of text in message
  1043. *--               F) Give a "windows" like title bar
  1044. *--               G) Allow for screens bigger'n 25 lines ... (EGA43, 
  1045. *--                  VGA50 ...)
  1046. *-- Written for.: dBASE IV, 1.5 or later
  1047. *-- Rev. History: 06/11/1993 -- Original
  1048. *-- Calls.......: Shadow
  1049. *--               Center
  1050. *--               Bord3D5
  1051. *--               WordWrap
  1052. *--               ColorBrk()
  1053. *--               FBClrBrk()
  1054. *--               Justify()
  1055. *-- Called by...: Any
  1056. *-- Usage.......: x=YesNo6(<lDefault>,<cWhere>,<cTitle>,<cMessage>,;
  1057. *--                        [<cColor>,[<nStyle>]])
  1058. *-- Example.....: if YesNo6(.t.,"CC","Delete Record?",;
  1059. *--                         "If you select [Yes] "+;
  1060. *--                         "you will delete this record.",cWind1,3)
  1061. *-- Returns.....: logical 
  1062. *-- Parameters..: lDefault = Which menu pad do you wish to default to?
  1063. *--                          .T. = "Yes", .F. = "No"
  1064. *--               cWhere   = Where on the screen do you wish the dialog 
  1065. *--                          box to appear?
  1066. *--                          UL = Upper Left
  1067. *--                          UC = Upper Center
  1068. *--                          UR = Upper Right
  1069. *--                          CL = Center Left
  1070. *--                          CC = Center Center (default)
  1071. *--                          CR = Center Right
  1072. *--                          BL = Bottom Left
  1073. *--                          BC = Bottom Center
  1074. *--                          BR = Bottom Right
  1075. *--               cTitle   = Title for the title bar, up to 30 char.
  1076. *--               cMessage = Message, up to 254 characters
  1077. *--               cColor   = Colors in standard foreground/background
  1078. *--                          If no colors given, you will get the 
  1079. *--                          Borland "steel grey", with black text. 
  1080. *--                          The(active) buttons and title bar will end
  1081. *--                          up bright white on black.
  1082. *--               nStyle   = Border Style
  1083. *--                          1 = Double Border, raised (default)
  1084. *--                          2 = Double Border, recessed
  1085. *--                          3 = Single Border, raised
  1086. *--                          4 = Single Border, recessed
  1087. *-----------------------------------------------------------------------
  1088.  
  1089.    parameters lDefault, cWhere, cTitle, cMessage, cColor, nStyle
  1090.    private nParm,nWidth,nHeight,cRow,cCol,nTop,nBottom,nLeft,nRight,;
  1091.            cTempCol
  1092.    private nBordCol,nButtonRow,cWindow,cScreen,nScreen
  1093.    
  1094.    *-- save current screen, save current window
  1095.    cWindow = window()
  1096.    save screen to sYesNo
  1097.    
  1098.    *-- determine # of parameters passed, and set defaults if necessary
  1099.    nParm = pcount()
  1100.    if nParm < 6          && no selection for border-style, set to def.
  1101.       m->nStyle = 1
  1102.    endif
  1103.    if m->nStyle < 1 .or. m->nStyle > 4  && don't screw with routine!
  1104.       m->nStyle = 1
  1105.    endif
  1106.    if nParm < 5                   && no colors parm, set to steel-grey
  1107.       m->cColor = "N/W,W+/N,N/W"
  1108.    endif
  1109.    if isblank(m->cColor)          && color field is empty, steel-grey
  1110.       m->cColor = "N/W,W+/N,N/W"
  1111.    endif
  1112.    if isblank(m->cWhere)         && default location is center of screen
  1113.       m->cWhere = "CC"
  1114.    endif
  1115.    
  1116.    m->nWidth = 36 + iif(m->nStyle < 3,4,2)    && width of dialog box
  1117.    
  1118.    *-- determine height of window by text
  1119.    *-- if the remainder of the length of the message/width is > 0
  1120.    *--    we have one more line of text, add 1, else add 0
  1121.    *-- border will determine more ... (if it's 1 or 2, it's double-size,
  1122.    *--    so we add 4 lines (top/bottom * 2), if it's 3 or 4, it's 
  1123.    *---   single ...)
  1124.    *-- add 2 rows for the title, and 3 for the menu, and 1 for the 
  1125.    *-- button borders ...
  1126.    m->nHeight = int(len(m->cMessage)/m->nWidth) + ;
  1127.                 iif(mod(len(m->cMessage),m->nWidth) > 0,1,0) +;
  1128.                 iif(m->nStyle < 3,3,1) + 6
  1129.    
  1130.    *-- now to determine window Coordinates
  1131.    m->cRow = left(m->cWhere,1)
  1132.    m->cCol = right(m->cWhere,1)
  1133.    
  1134.    *-- get screen height
  1135.    m->cScreen = SET("DISPLAY")
  1136.    if m->cScreen = "MONO"
  1137.       m->nScreen = 24
  1138.    else
  1139.       m->nScreen = val(right(m->cScreen,2)) - 1  && (EGA25 = 0 to 24)
  1140.    endif
  1141.    
  1142.    *-- this is where we _really_ determine the coordinates
  1143.    do case   && first let's get the rows (top/bottom)
  1144.       case m->cRow = "U"
  1145.          m->nTop = 1
  1146.       case m->cRow ="B"
  1147.          m->nTop = (m->nScreen - m->nHeight - 2) 
  1148.       otherwise  && "C" or center ...
  1149.          m->nTop = (m->nScreen - m->nHeight) / 2
  1150.    endcase
  1151.    m->nBottom = m->nTop + m->nHeight
  1152.    
  1153.    do case   && now for the columns
  1154.       case m->cCol = "L"
  1155.          m->nLeft = 5
  1156.       case m->cCol = "R"
  1157.          m->nLeft = 35
  1158.       otherwise && "C" or center
  1159.          m->nLeft = 20
  1160.    endcase
  1161.    m->nRight = m->nLeft + m->nWidth
  1162.    
  1163.    *-- define window
  1164.    activate screen
  1165.    define window wYesNo from m->nTop,m->nLeft to ;
  1166.                              m->nBottom,m->nRight NONE color &cColor.
  1167.    
  1168.    *-- define menu
  1169.    define menu mYesNo
  1170.    m->nButtonRow = m->nHeight - iif(m->nStyle<3,3,2)
  1171.    define pad pYes of mYesNo prompt "[Yes]" at m->nButtonRow,10
  1172.    define pad pNo  of mYesNo prompt "[No]"  at m->nButtonRow,25
  1173.    on selection pad pYes of mYesNo deactivate menu
  1174.    on selection pad pNo  of mYesNo deactivate menu
  1175.    
  1176.    *-- activate window
  1177.    do shadow with m->nTop,m->nLeft,m->nBottom,m->nRight
  1178.    activate window wYesNo
  1179.    
  1180.    *-- draw border
  1181.    m->cBordCol = left(m->cColor,at(",",m->cColor)-1)
  1182.    do Bord3D5 with 0,0,m->nHeight,m->nWidth,m->cBordCol,m->nStyle 
  1183.    
  1184.    *-- display title
  1185.    if len(m->cTitle) < m->nWidth
  1186.       m->cTitle = justify(m->cTitle,35,"C")
  1187.       if len(m->cTitle) < 35
  1188.          m->cTitle = m->cTitle + " "
  1189.       endif
  1190.    endif
  1191.    m->cTempCol = colorbrk(m->cColor,2)
  1192.    m->cColorF  = FBClrBrk("B",m->cTempCol)
  1193.    m->cColorB  = FBClrBrk("B",colorbrk(m->cColor,1))
  1194.    m->cColorAll= m->cColorF+"/"+m->cColorB
  1195.    m->nRow = iif(m->nStyle < 3,2,1)
  1196.    m->nCol = iif(m->nStyle < 3,3,2)
  1197.    @m->nRow,  m->nCol say m->cTitle color &cTempCol.
  1198.    @m->nRow+1,m->nCol say replicate(chr(223),35) color &cColorAll.
  1199.    
  1200.    *-- display text
  1201.    do WordWrap with iif(m->nStyle<3,4,3),;
  1202.                     iif(m->nStyle<3,4,3),m->cMessage,34
  1203.    
  1204.    *-- set Y/N keys for menu pad
  1205.    clear typeahead && just to be safe
  1206.    on key label Y keyboard iif(pad() = "PYES","",chr(19))+chr(13)
  1207.    on key label N keyboard iif(pad() = "PNO" ,"",chr(4) )+chr(13)
  1208.    
  1209.    *-- deal with borders around the pads ...
  1210.    do bord3d5 with m->nButtonRow-1, 9,m->nButtonRow+1,15,m->cBordCol,3
  1211.    do bord3d5 with m->nButtonRow-1,24,m->nButtonRow+1,29,m->cBordCol,3
  1212.    
  1213.    *-- activate menu
  1214.    if m->lDefault
  1215.       activate menu mYesNo pad pYes
  1216.    else
  1217.       activate menu mYesNo pad pNo
  1218.    endif
  1219.    
  1220.    *-- cleanup
  1221.    on key label Y
  1222.    on key label N
  1223.    release window wYesNo
  1224.    restore screen from sYesNo
  1225.    release screen sYesNo
  1226.    release menu mYesNo
  1227.    if .not. isblank(m->cWindow)
  1228.       activate window &cWindow.
  1229.    endif
  1230.    
  1231. RETURN iif(pad() = "PYES",.T.,.F.)
  1232. *-- EoF: YesNo6()
  1233.  
  1234. FUNCTION YesNoCan
  1235. *-----------------------------------------------------------------------
  1236. *-- Programmer..: Miriam Liskin
  1237. *-- Date........: 02/01/1993
  1238. *-- Notes.......: Asks a yes/no/cancel question in a dialog window/box
  1239. *-- Written for.: dBASE IV, 1.1
  1240. *-- Rev. History: 04/19/1991 - Modified by Ken Mayer to become a 
  1241. *--                            function
  1242. *--               04/29/1991 - Modified to Ken Mayer add shadow
  1243. *--               05/13/1991 - Modified to Ken Mayer remove need for 
  1244. *--                            extra procedures (YES/NO) that were used
  1245. *--                            for returning values from Menu
  1246. *--                            (suggested by Clinton L. Warren (VBCES))
  1247. *--               01/20/1992 - Modified by Martin Leon (HMan) to handle 
  1248. *--                            user pressing 'Y' or 'N' keys (with ON 
  1249. *--                            KEY ...).
  1250. *--               06/11/1992 - Modified by Joey Carroll (JOEY) to allow
  1251. *--                            answer choices to be "Yes", "No", or 
  1252. *--                            "Cancel" or to allow for parameters to 
  1253. *--                            pass the contents of the prompts. If 
  1254. *--                            none are passed, they default
  1255. *--                            to "Yes", "No", "Cancel". Further 
  1256. *--                            modified to allow specification of 
  1257. *--                            location by row if desired. Window size 
  1258. *--                            now varies as parameters dictate.
  1259. *--               09/21/1992 - Modified by JOEY to fix bug caused if 
  1260. *--                            leading blanks in parameters cPrompt1,
  1261. *--                            cPrompt2,cPrompt3
  1262. *--                            Corrected example - case pad()="PPAD1"
  1263. *--                            instead of          case pad()=PPAD1
  1264. *--               02/01/1993 - Mods by Lee Hite: Routine would not wait 
  1265. *--                            for user response if "default" answer 
  1266. *--                            did not match one of the prompts. Now 
  1267. *--                            first prompt becomes default if no match
  1268. *--                            is found on invocation. Also, match is 
  1269. *--                            no longer case sensitive.  Also made 
  1270. *--                            window height variable if message
  1271. *--                            lines 2 and/or 3 are null strings.  
  1272. *--                            Finally, added "confirmation" parameter
  1273. *--                            which when set true will force user to 
  1274. *--                            press [Enter] before function returns.
  1275. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  1276. *--               CENTER               Procedure in PROC.PRG
  1277. *--               ISBLANK()            Function in MISC.PRG, 
  1278. *--                                                    Internal in 1.5
  1279. *-- Called by...: Any
  1280. *-- Usage.......: YesNoCan("<cAnswer>","<cMess1>","<cMess2>",;
  1281. *--                        ["<cMess3>",;["<cPrompt1>",["<cPrompt2>",;
  1282. *--                        ["<cPrompt3>",[<nTopRow>,["<cColor>",;
  1283. *--                        [lConfirm]]]]]]])
  1284. *-- Example.....: cAnswer="Y"
  1285. *--               cAnswer=YesNoCan(cAnswer,"*** Warning ***",;
  1286. *--                            "A serious error has occured.",;
  1287. *--                             "Choose carefully.","Proceed",;
  1288. *--                             "Retry","Cancel",10,;
  1289. *--                             "w+/r,n/w,w+/r")
  1290. *--               do case
  1291. *--                  case cAnswer="Y"    && OR case pad()="PPAD1"
  1292. *--                     * do your thing
  1293. *--                  case cAnswer="N"    && OR case pad()="PPAD2"
  1294. *--                     skip
  1295. *--                  case cAnswer="C"    && OR case pad()="PPAD3"
  1296. *--                     * e.g. - return
  1297. *--               endcase
  1298. *--
  1299. *--                 The middle set of colors should be different, as 
  1300. *--                 they will be the colors of the YES/NO selections 
  1301. *--                 Options may be blank by using nul values ("")
  1302. *-- Returns.....: First character of selected pad
  1303. *-- Parameters..: cAnswer  =  default value (Yes or No or Cancel) for 
  1304. *--                           menu
  1305. *--               cMess1   =  First line of Message
  1306. *--               cMess2   =  Second line of message
  1307. *--               cMess3   =  Third line of message
  1308. *--               cPrompt1 =  Optional prompt for left pad
  1309. *--               cPrompt2 =  Optional prompt for middle pad
  1310. *--               cPrompt3 =  Optional prompt for right pad
  1311. *--               nTopRow  =  Optional top row of window
  1312. *--               cColor   =  Optional colors for window/menu/box
  1313. *--               lConfirm =  Optional "confirmation" parameter -- if 
  1314. *--                           true user must press [Enter], otherwise
  1315. *--                           pressing a valid prompt key automatically
  1316. *--                           returns
  1317. *-----------------------------------------------------------------------
  1318.  
  1319.    parameter cAnswer,cMess1,cMess2,cMess3,;
  1320.       cPrompt1,cPrompt2,cPrompt3,nTopRow,cColor,lConfirm
  1321.    private nLMargin,nRMargin,lWrap,nTopRowMax,cKey1,cKey2,cKey3,;
  1322.       nWinWidth, cConfirm, nWinHgth, nMsgRow
  1323.    private cPrompt1,cPrompt2,cPrompt3 
  1324.    
  1325.    *-- save screen so we can restore ...
  1326.    save screen to sYesNoCan
  1327.    * locate top row of window
  1328.    m->nTopRowMax = iif(set("STATUS") = "OFF",17,14) 
  1329.                                            && protect Status Line
  1330.    m->nTopRow = iif(isblank(m->nTopRow),14,m->nTopRow) 
  1331.                                            && no parameter passed
  1332.    m->nTopRow = min(m->nTopRowMax,m->nTopRow)
  1333.  
  1334.    * set pad prompts if none passed
  1335.    m->cPrompt1 = iif(isblank(m->cPrompt1),"Yes",m->cPrompt1)
  1336.    m->cPrompt2 = iif(isblank(m->cPrompt2),"No",m->cPrompt2)
  1337.    m->cPrompt3 = iif(isblank(m->cPrompt3),"Cancel",m->cPrompt3)
  1338.    m->cAnswer = iif(isblank(m->cAnswer),m->cPrompt1,m->cAnswer)
  1339.  
  1340.    * program bombs if prompts passed contain leading blanks
  1341.    m->cPrompt1 = ltrim(trim(m->cPrompt1))
  1342.    m->cPrompt2 = ltrim(trim(m->cPrompt2))
  1343.    m->cPrompt3 = ltrim(trim(m->cPrompt3))
  1344.  
  1345.    * determine how wide the window needs to be
  1346.    m->nWinWidth = max(19,len(m->cPrompt1 + m->cPrompt2 + ;
  1347.                                            m->cPrompt3) +13)
  1348.    m->nWinWidth = max(m->nWinWidth,len(m->cMess1)+4)
  1349.    m->nWinWidth = max(m->nWinWidth,len(m->cMess2)+4)
  1350.    m->nWinWidth = max(m->nWinWidth,len(m->cMess3)+4)
  1351.    * and how high it needs to be
  1352.    m->nWinHgth = iif(""=m->cMess2,7,8)
  1353.    m->nWinHgth = iif(""=m->cMess3,m->nWinHgth-1,m->nWinHgth)
  1354.    * and center it
  1355.    define window wYesNoCan from m->nTopRow,40-(m->nWinWidth+2)/2 ;
  1356.       to m->nTopRow+m->nWinHgth-1,40+(m->nWinWidth+2)/2 double ;
  1357.       color &cColor.
  1358.    define menu mYesNoCan
  1359.    define pad pPad1 of mYesNoCan Prompt "["+m->cPrompt1+"]" ;
  1360.       at m->nWinHgth-3,02
  1361.    * center middle prompt between other two, not center of window
  1362.    define pad pPad2 of mYesNoCan Prompt "["+m->cPrompt2+"]" at ;
  1363.       m->nWinHgth-3, ((m->nWinWidth-len(m->cPrompt2))/2+;
  1364.       (len(m->cPrompt1)-len(m->cPrompt3))/2)
  1365.    define pad pPad3 of mYesNoCan Prompt "["+m->cPrompt3+"]"  ;
  1366.       at m->nWinHgth-3,(m->nWinWidth-3)-(len(m->cPrompt3))
  1367.    on selection pad pPad1 of mYesNoCan deactivate menu
  1368.    on selection pad pPad2 of mYesNoCan deactivate menu
  1369.    on selection pad pPad3 of mYesNoCan deactivate menu
  1370.    
  1371.    activate screen
  1372.    do shadow with m->nTopRow,40-(m->nWinWidth+2)/2,m->nTopRow+;
  1373.       m->nWinHgth-1, 40+(m->nWinWidth+2)/2
  1374.    activate window wYesNoCan
  1375.    
  1376.    do center with 0,m->nWinWidth,"",m->cMess1       && center the text
  1377.    *-- deal with blank message lines
  1378.    m->nMsgRow = 2
  1379.    if "" <> m->cMess2
  1380.       do center with m->nMsgRow,m->nWinWidth,"",m->cMess2
  1381.       m->nMsgRow = m->nMsgRow + 1
  1382.    endif
  1383.    if "" <> m->cMess3
  1384.       do center with m->nMsgRow,m->nWinWidth,"",m->cMess3
  1385.    endif
  1386.    *-- deal with user pressing first key of prompt
  1387.    m->cKey1 = left(m->cPrompt1,1)
  1388.    m->cKey2 = left(m->cPrompt2,1)
  1389.    m->cKey3 = left(m->cPrompt3,1)
  1390.    *-- set [CR] at end of keyboard command depending on "confirm" 
  1391.    *-- parameter
  1392.    m->cConfirm = iif(m->lConfirm,"",chr(13))
  1393.  
  1394.    on key label &cKey1. keyboard iif( PAD() = "PPAD1", "", ;
  1395.       iif(pad() = "PPAD2", chr(19),CHR(4) )) + m->cConfirm
  1396.    on key label &cKey2. keyboard iif( PAD() = "PPAD2",  "", ;
  1397.       iif(pad() = "PPAD1",CHR(4),chr(19) )) + m->cConfirm
  1398.    on key label &cKey3. keyboard iif( PAD() = "PPAD3", "", ;
  1399.       iif(pad() = "PPAD2", CHR(4),chr(19))) + m->cConfirm
  1400.    clear typeahead
  1401.    *-- otherwise deal with regular "menu" abilities
  1402.    do case
  1403.       case upper(m->cAnswer)=upper(m->cKey1)
  1404.            activate menu mYesNoCan pad pPad1
  1405.       case upper(m->cAnswer)=upper(m->cKey2)
  1406.            activate menu mYesNoCan pad pPad2
  1407.       case upper(m->cAnswer)=upper(m->cKey3)
  1408.            activate menu mYesNoCan pad pPad3
  1409.       otherwise
  1410.            activate menu mYesNoCan pad pPad1
  1411.    endcase
  1412.    
  1413.    *-- clear out ON KEY settings ...
  1414.    on key label &cKey1.
  1415.    on key label &cKey2.
  1416.    on key label &cKey3.
  1417.    *-- reset environment
  1418.    release window wYesNoCan
  1419.    restore screen from sYesNoCan
  1420.    release screen sYesNoCan
  1421.    release menu mYesNoCan
  1422.  
  1423. RETURN upper(substr(prompt(),2,1))
  1424. *-- EoF: YesNoCan()
  1425.  
  1426. FUNCTION YNC
  1427. *-----------------------------------------------------------------------
  1428. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  1429. *-- Date........: 06/24/1993
  1430. *-- Notes.......: This is a variation of YESNO(), designed to allow the
  1431. *--               programmer to give the user three buttons, instead of
  1432. *--               two -- "Yes", "No" and "Cancel". The one MAJOR 
  1433. *--               difference is the logical parameter "lDefault" must 
  1434. *--               be changed to character, and the returned value will
  1435. *--               also be character. The work involved is based on work
  1436. *--               by Miriam Liskin, Martin Leon, Clinton Warren,
  1437. *--               Joey D. Carol, and myself. 
  1438. *--               This Yes/No dialog box should do the following:
  1439. *--               A) Full 3-D effect(s)
  1440. *--               B) Color options up to programmer/user
  1441. *--               C) YES/NO buttons at bottom of dialog box
  1442. *--               D) Allow for location on screen
  1443. *--               E) Allow for up to 256 characters of text in message
  1444. *--               F) Give a "windows" like title bar
  1445. *--               G) Allow for screens bigger'n 25 lines ... (EGA43, 
  1446. *--                  VGA50 ...)
  1447. *-- Written for.: dBASE IV, 1.5 or later
  1448. *-- Rev. History: 06/24/1993 -- Original
  1449. *-- Calls.......: Shadow              Procedure in PROC.PRG
  1450. *--               Center              Procedure in PROC.PRG
  1451. *--               Bord3D              Procedure in PROC.PRG
  1452. *--               WordWrap            Procedure in PROC.PRG
  1453. *--               ColorBrk()          Function in PROC.PRG
  1454. *--               FBClrBrk()          Function in PROC.PRG
  1455. *--               Justify()           Function in PROC.PRG
  1456. *-- Called by...: Any
  1457. *-- Usage.......: x=YNC(<cDefault>,<cWhere>,<cTitle>,<cMessage>,;
  1458. *--                     [<cColor>,[<nStyle>]])
  1459. *-- Example.....: x= YNC("Y","CC","Delete Record?",;
  1460. *--                               "If you select [Yes] "+;
  1461. *--                         "you will delete this record.",cWind1,3)
  1462. *--               do case
  1463. *--                  case x = "Y"
  1464. *--                       * do "Yes" action
  1465. *--                  case x = "N:
  1466. *--                       * do "No" action
  1467. *--                  otherwise
  1468. *--                       *-- do "Cancel" action
  1469. *--               endcase
  1470. *-- Returns.....: Character (first char of button)
  1471. *-- Parameters..: cDefault = Which menu pad do you wish to default to?
  1472. *--                          "Y" = "Yes", "N" = "No", "C" = "Cancel"
  1473. *--               cWhere   = Where on the screen do you wish the dialog 
  1474. *--                          box to appear?
  1475. *--                          UL = Upper Left
  1476. *--                          UC = Upper Center
  1477. *--                          UR = Upper Right
  1478. *--                          CL = Center Left
  1479. *--                          CC = Center Center (default)
  1480. *--                          CR = Center Right
  1481. *--                          BL = Bottom Left
  1482. *--                          BC = Bottom Center
  1483. *--                          BR = Bottom Right
  1484. *--               cTitle   = Title for the title bar, up to 30 
  1485. *--                          characters
  1486. *--               cMessage = Message, up to 254 characters
  1487. *--               cColor   = Colors in standard foreground/background 
  1488. *--                          If no colors given, you will get the 
  1489. *--                          Borland "steel grey", with black text. The
  1490. *--                          (active) buttons and title bar will end up
  1491. *--                          bright white on black.
  1492. *--               nStyle   = Border Style
  1493. *--                          1 = Double Border, raised (default)
  1494. *--                          2 = Double Border, recessed
  1495. *--                          3 = Single Border, raised
  1496. *--                          4 = Single Border, recessed
  1497. *-----------------------------------------------------------------------
  1498.  
  1499.    parameters cDefault, cWhere, cTitle, cMessage, cColor, nStyle
  1500.    private nParm,nWidth,nHeight,cRow,cCol,nTop,nBottom,nLeft,nRight,;
  1501.            cTempCol
  1502.    private nBordCol,nButtonRow,cWindow,cScreen,nScreen
  1503.    
  1504.    *-- save current screen, save current window
  1505.    cWindow = window()
  1506.    save screen to sYesNo
  1507.    
  1508.    *-- determine # of parameters passed, and set defaults if necessary
  1509.    m->nParm = pcount()
  1510.    if m->nParm < 6            && no selection for border-style, set to def.
  1511.       m->nStyle = 1
  1512.    endif
  1513.    if m->nStyle < 1 .or. m->nStyle > 4  && don't screw with my routine!
  1514.       m->nStyle = 1
  1515.    endif
  1516.    if m->nParm < 5                   && no colors, set to steel-grey
  1517.       m->cColor = "N/W,W+/N,N/W"
  1518.    endif
  1519.    if isblank(m->cColor)
  1520.       m->cColor = "N/W,W+/N,N/W"
  1521.    endif
  1522.    if isblank(m->cWhere)         && default location is center of screen
  1523.       m->cWhere = "CC"
  1524.    endif
  1525.    
  1526.    *-- set some defaults
  1527.    m->nWidth = 36 + iif(m->nStyle < 3,4,2)    && width of dialog box
  1528.    
  1529.    *-- determine height of window by text
  1530.    *-- if the remainder of the length of the message/width is > 0
  1531.    *--    we have one more line of text, add 1, else add 0
  1532.    *-- border will determine more ... (if it's 1 or 2, it's double-size,
  1533.    *--    so we add 4 lines (top/bottom * 2), if it's 3 or 4, it's 
  1534.    *--    single ...)
  1535.    *-- add 2 rows for the title, and 3 for the menu, and 1 for the 
  1536.    *-- button borders ...
  1537.    m->nHeight = int(len(m->cMessage)/m->nWidth) + ;
  1538.              iif(mod(len(m->cMessage),m->nWidth) > 0,1,0) +;
  1539.              iif(m->nStyle < 3,3,1) + 6
  1540.    
  1541.    *-- now to determine window Coordinates
  1542.    m->cRow = left(m->cWhere,1)
  1543.    m->cCol = right(m->cWhere,1)
  1544.    
  1545.    *-- get screen height
  1546.    m->cScreen = SET("DISPLAY")
  1547.    if m->cScreen = "MONO"
  1548.       m->nScreen = 24
  1549.    else
  1550.       m->nScreen = val(right(m->cScreen,2)) - 1  && (EGA25 = 0 to 24)
  1551.    endif
  1552.    
  1553.    *-- this is where we _really_ determine the coordinates
  1554.    do case   && first let's get the rows (top/bottom)
  1555.       case m->cRow = "U"
  1556.          m->nTop = 1
  1557.       case m->cRow ="B"
  1558.          m->nTop = (m->nScreen - m->nHeight - 2)  
  1559.       otherwise  && "C" or center ...
  1560.          m->nTop = (m->nScreen - m->nHeight) / 2
  1561.    endcase
  1562.    m->nBottom = m->nTop + m->nHeight
  1563.    
  1564.    do case   && now for the columns
  1565.       case m->cCol = "L"
  1566.          m->nLeft = 5
  1567.       case m->cCol = "R"
  1568.          m->nLeft = 35
  1569.       otherwise && "C" or center
  1570.          m->nLeft = 20
  1571.    endcase
  1572.    m->nRight = m->nLeft + m->nWidth
  1573.    
  1574.    *-- define window
  1575.    activate screen
  1576.    define window wYesNo from m->nTop,m->nLeft to ;
  1577.                              m->nBottom,m->nRight NONE color &cColor.
  1578.    
  1579.    *-- define menu
  1580.    define menu mYesNo
  1581.    m->nButtonRow = m->nHeight - iif(m->nStyle<3,3,2)
  1582.    m->nYes = 5             && column for "[Yes]"    button
  1583.    m->nNo  = (m->nWidth-6)/2  && column for "[No]"  button -- center it
  1584.    m->nCan = (m->nWidth-13)   && column for "[Cancel]" button -- from rt
  1585.    define pad pYes of mYesNo prompt "[Yes]"    at m->nButtonRow,m->nYes
  1586.    define pad pNo  of mYesNo prompt "[No]"     at m->nButtonRow,m->nNo
  1587.    define pad pCan of mYesNo prompt "[Cancel]" at m->nButtonRow,m->nCan
  1588.    on selection pad pYes of mYesNo deactivate menu
  1589.    on selection pad pNo  of mYesNo deactivate menu
  1590.    on selection pad pCan of mYesNo deactivate menu
  1591.    
  1592.    *-- activate window
  1593.    do shadow with m->nTop,m->nLeft,m->nBottom,m->nRight
  1594.    activate window wYesNo
  1595.    
  1596.    *-- draw border
  1597.    m->cBordCol = left(m->cColor,at(",",m->cColor)-1)
  1598.    do bord3d with 0,0,m->nHeight,m->nWidth,m->cBordCol,m->nStyle 
  1599.    
  1600.    *-- display title
  1601.    if len(m->cTitle) < m->nWidth
  1602.       m->cTitle = justify(m->cTitle,35,"C")
  1603.       if len(m->cTitle) < 35
  1604.          m->cTitle = m->cTitle + " "
  1605.       endif
  1606.    endif
  1607.    m->cTempCol = colorbrk(m->cColor,2)
  1608.    m->cColorF  = FBClrBrk("B",m->cTempCol)
  1609.    m->cColorB  = FBClrBrk("B",colorbrk(m->cColor,1))
  1610.    m->cColorAll= m->cColorF+"/"+m->cColorB
  1611.    m->nRow = iif(m->nStyle < 3,2,1)
  1612.    m->nCol = iif(m->nStyle < 3,3,2)
  1613.    @m->nRow,  m->nCol say m->cTitle color &cTempCol.
  1614.    @m->nRow+1,m->nCol say replicate(chr(223),35) color &cColorAll.
  1615.    
  1616.    *-- display text
  1617.    do WordWrap with iif(m->nStyle<3,4,3),;
  1618.                     iif(m->nStyle<3,4,3),m->cMessage,34
  1619.    
  1620.    *-- set Y/N keys for menu pad
  1621.    clear typeahead && just to be safe
  1622.    *-- if we're ON the pad user selected, do nothing, else go left or
  1623.    *-- right as needed, and then issue a "Return" (chr(13))
  1624.    on key label Y keyboard iif(pad() = "PYES","",;
  1625.       iif(pad()="PNO",chr(19),chr(4) ) )+chr(13)
  1626.    on key label N keyboard iif(pad() = "PNO" ,"",;
  1627.       iif(pad()="PYES",chr(4),chr(19) ) )+chr(13)
  1628.    on key label C keyboard iif(pad() = "PCAN","",;
  1629.       iif(pad()="PNO",chr(4),chr(19) ) )+chr(13)
  1630.    
  1631.    *-- deal with borders around the pads ...
  1632.    do bord3d with m->nButtonRow-1,m->nYes-1,m->nButtonRow+1,;
  1633.                   m->nYes+5,m->cBordCol,3
  1634.    do bord3d with m->nButtonRow-1,m->nNo-1, m->nButtonRow+1,;
  1635.                   m->nNo+4, m->cBordCol,3
  1636.    do bord3d with m->nButtonRow-1,m->nCan-1,m->nButtonRow+1,;
  1637.                   m->nCan+8,m->cBordCol,3
  1638.    
  1639.    *-- activate menu
  1640.    do case
  1641.       case upper(m->cDefault) = "Y"
  1642.          activate menu mYesNo pad pYes
  1643.       case upper(m->cDefault) = "N"
  1644.          activate menu mYesNo pad pNo
  1645.       case (m->cDefault) = "C"
  1646.          activate menu mYesNo pad pCan
  1647.       otherwise  && default to 'Yes'
  1648.          activate menu mYesNo pad pYes
  1649.    endcase
  1650.    
  1651.    *-- cleanup
  1652.    on key label Y
  1653.    on key label N
  1654.    on key label C
  1655.    release window wYesNo
  1656.    restore screen from sYesNo
  1657.    release screen sYesNo
  1658.    release menu mYesNo
  1659.    if .not. isblank(m->cWindow)
  1660.       activate window &cWindow.
  1661.    endif
  1662.          
  1663. RETURN substr(pad(),2,1)
  1664. *-- EoF: YNC()
  1665.  
  1666. FUNCTION Dialog
  1667. *-----------------------------------------------------------------------
  1668. *-- Programmer..: Larry Quaglia (Borland)
  1669. *-- Date........: 06/09/1992
  1670. *-- Notes.......: This routine provides a 'standard' set of dialogue 
  1671. *--               boxes and buttons for all applications. The concept 
  1672. *--               is to provide standardization for your apps. Taken 
  1673. *--               from TECHNOTES.
  1674. *-- Written for.: dBASE IV, 1.1
  1675. *-- Rev. History: 11/01/1991 -- first published in TechNotes.
  1676. *--               06/09/1992 -- Modified to handle explicit colors, 
  1677. *--               changed the color parameters a tad ... (Ken Mayer)
  1678. *-- Calls.......: SHADOW               Function in PROC.PRG
  1679. *--               RECOLOR              Procedure in PROC.PRG
  1680. *-- Called by...: Any
  1681. *-- Usage.......: Dialog("<cMsg>",<nType>,"<cBorder>",<nDefBut>,;
  1682. *--                       <lShadow>,"<cWind>","<cButton>")
  1683. *-- Example.....: Dialog("We have completed the transaction.",0,;
  1684. *--                      "DOUBLE",0,.t.,"RG+/GB","W+/N")
  1685. *-- Returns.....: Character -- Either 'ERROR' or title of Button.
  1686. *-- Parameters..: cMsg    = Message to be displayed -- maximum of 78
  1687. *--                         characters (one line only)
  1688. *--               nType   = Dialogue box TYPE. Options are 0 to 5:
  1689. *--                         0:   'OK'
  1690. *--                         1: 'OK'  'CANCEL'
  1691. *--                         2: 'ABORT'  'RETRY'  'IGNORE'
  1692. *--                         3: 'YES'  'NO'  'CANCEL'
  1693. *--                         4: 'YES'  'NO'
  1694. *--                         5: 'RETRY' 'CANCEL'
  1695. *--               cBorder = Border Style -- options are: "" (null) for 
  1696. *--                         SINGLE, DOUBLE or PANEL.
  1697. *--               nDefBut = Default Button. 
  1698. *--               lShadow = Display with a shadow or not (both on window
  1699. *--                         and buttons)?
  1700. *--               cWind   = Window Colors (must be valid dBASE color 
  1701. *--                         combo: i.e., "RG+/GB")
  1702. *--               cButton = Highlighted Button Color (Same as above, 
  1703. *--                         should contrast ...)
  1704. *-----------------------------------------------------------------------
  1705.  
  1706.    parameters cMsg,nType,cBorder,nDefBut,lShadow,cWind,cButton
  1707.    private nMsgLen,cNewColor,aButton,nMaxLine,nY,nBoxLen,nNumButton,;
  1708.            nCounter,nBasex,nYCol,nMsgLoc,cCurColor
  1709.  
  1710.    save screen to sDialog         && so we can restore at end of routine
  1711.    
  1712.    *-- determine length of message
  1713.    m->nMsgLen = len(trim(ltrim(m->cMsg))) + 1
  1714.    
  1715.    *-- Check for valid parms
  1716.    do case
  1717.       case m->nMsgLen > 78
  1718.          RETURN "ERROR - Message Length"
  1719.       case .not. (upper(m->cBorder) = "DOUBLE" .or. upper(m->cBorder)=;
  1720.          "PANEL" .or. len(trim(m->cBorder)) = 0)
  1721.          RETURN "ERROR - Border"
  1722.    endcase
  1723.    
  1724.    *-- save current color info and set color to user-defined
  1725.    m->cCurColor = set("ATTRIBUTES")
  1726.    set color of normal    to &cWind.
  1727.    set color of box       to &cWind.
  1728.    set color of message   to &cWind.
  1729.    set color of highlight to &cButton.
  1730.    
  1731.    *-- Allow use of <Tab> to move from button to button
  1732.    on key label tab keyboard chr(4)  && act as if right arrow were 
  1733.                                      && pushed
  1734.    
  1735.    *-- Define button array -- max of 3 buttons (at the moment)
  1736.    declare aButton[3]
  1737.    aButton[1] = ""
  1738.    aButton[2] = ""
  1739.    aButton[3] = ""
  1740.    
  1741.    *-- Establish screen height to properly center dialogue box
  1742.    m->nMaxLine = iif(right(set("DISP"),2) = "43",43,24)
  1743.    
  1744.    *-- Determine length of passed "message" parameter. If long enough, 
  1745.    *-- make the dialog box a little bigger. If very short, make it just 
  1746.    *-- big enough to accomodate the three buttons.
  1747.    m->nY = iif(int(m->nMsgLen) > 30,int(m->nMsgLen/2)+2,24)
  1748.    m->nBoxLen = 2 * m->nY
  1749.    
  1750.    *-- Setup the window and determine if shadow ... if yes, call shadow
  1751.    define window wDialog from int(m->nMaxLine/2)-5,40-m->nY to ;
  1752.                          int(m->nMaxLine/2)+4,40+m->nY &cBorder.
  1753.    if m->lShadow
  1754.       activate screen
  1755.       do shadow with int(m->nMaxLine/2)-5,40-m->nY,;
  1756.                      int(m->nMaxLine/2)+4,40+m->nY
  1757.    endif
  1758.    activate window wDialog
  1759.    clear
  1760.    
  1761.    *-- Determine the type of buttons and set appropriate parms.
  1762.    *-- These could be modified to your own needs.
  1763.    do case
  1764.       case m->nType = 0
  1765.          m->nNumButton = 1
  1766.          aButton[1] = "   OK   "
  1767.       case m->nType = 1
  1768.          m->nNumButton = 2
  1769.          aButton[1] = "   OK   "
  1770.          aButton[2] = " CANCEL "
  1771.       case m->nType = 2
  1772.          m->nNumButton = 3
  1773.          aButton[1] = " ABORT  "
  1774.          aButton[2] = " RETRY  "
  1775.          aButton[3] = " IGNORE "
  1776.       case m->nType = 3
  1777.          m->nNumButton = 3
  1778.          aButton[1] = "   YES  "
  1779.          aButton[2] = "   NO   "
  1780.          aButton[3] = " CANCEL "
  1781.       case m->nType = 4
  1782.          m->nNumButton = 2
  1783.          aButton[1] = "   YES  "
  1784.          aButton[2] = "   NO   "
  1785.       case m->nType = 5
  1786.          m->nNumButton = 2
  1787.          aButton[1] = " RETRY  "
  1788.          aButton[2] = " CANCEL "
  1789.    endcase
  1790.    
  1791.    *-- Get dialog box length to create a bar menu of appropriate size.
  1792.    *-- Define the bar menu in a loop. Deactivate it upon selection of
  1793.    *-- one of the buttons.
  1794.    m->nCounter = 1
  1795.    m->nBaseX = m->nBoxLen / (m->nNumButton + 1)
  1796.    define menu mDialog
  1797.    do while m->nCounter <= m->nNumButton
  1798.       pPadName = "PAD"+str(m->nCounter,1)  && pad name is 'PAD #'
  1799.       m->nYCol = (m->nCounter * m->nBaseX) - ;
  1800.                  (int(len(aButton[m->nCounter]) /2))
  1801.       define pad &pPadName of mDialog prompt aButton[m->nCounter] ;
  1802.                  at 4,m->nYCol
  1803.       
  1804.       *-- If shadow is on, put shadows on buttons as well ...
  1805.       if m->lShadow
  1806.          activate screen
  1807.          do shadow with 3,m->nYCol-2,5,m->nYCol+;
  1808.                         (len(aButton[m->nCounter]))-1
  1809.       endif
  1810.       @3,m->nYCol-1 to 5,m->nYCol+(len(aButton[m->nCounter])) 
  1811.                                     && box around button
  1812.       on selection pad &pPadName. of mDialog deactivate menu
  1813.       m->nCounter = m->nCounter + 1
  1814.    enddo
  1815.    
  1816.    *-- place message (centered in box)
  1817.    m->nMsgLoc = int(m->nBoxLen/2) - int(m->nMsgLen/2)
  1818.    @1,m->nMsgLoc say m->cMsg
  1819.    
  1820.    *-- place cursor to the default button specified by the user
  1821.    m->nCounter = 1
  1822.    do while m->nCounter < m->nDefBut
  1823.       keyboard chr(4)
  1824.       m->nCounter = m->nCounter + 1
  1825.    enddo
  1826.    
  1827.    *-- Activate the whole thing, and return the button name
  1828.    activate menu mDialog
  1829.    m->cValue = trim(ltrim(prompt()))
  1830.    
  1831.    *-- deactivate it all, restore screen, etc.
  1832.    release window wDialog
  1833.    release menu mDialog
  1834.    restore screen from sDialog
  1835.    release screen sDialog
  1836.    do ReColor with m->cCurColor
  1837.    on key label tab
  1838.    
  1839. RETURN m->cValue
  1840. *-- EoF: Dialog()
  1841.  
  1842. FUNCTION DIALOG2
  1843. *-----------------------------------------------------------------------
  1844. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  1845. *-- Date........: 06/30/1993
  1846. *-- Notes.......: This is a variation of YESNO(), designed to allow the
  1847. *--               programmer to give the user up to three buttons, 
  1848. *--               allowing them to select the ones they want, either by
  1849. *--               choosing one of the options listed, or passing as 
  1850. *--               parameters up to three  selections for button titles. 
  1851. *-- Written for.: dBASE IV, 1.5 or later
  1852. *-- Rev. History: 06/24/1993 -- Original
  1853. *-- Calls.......: Shadow              Procedure in PROC.PRG
  1854. *--               Center              Procedure in PROC.PRG
  1855. *--               Bord3D              Procedure in PROC.PRG
  1856. *--               WordWrap            Procedure in PROC.PRG
  1857. *--               ColorBrk()          Function in PROC.PRG
  1858. *--               FBClrBrk()          Function in PROC.PRG
  1859. *--               Justify()           Function in PROC.PRG
  1860. *-- Called by...: Any
  1861. *-- Usage.......: x=DIALOG2(<nType>,<nDefault>,<cWhere>,<cTitle>,;
  1862. *--                         <cMessage>,<cColor>,<nStyle>,[<cButton1>,;
  1863. *--                         <cButton2>,<cButton3>])
  1864. *-- Example.....: x= DIALOG2(1,1,"CC","Delete Record?",;
  1865. *--                          "If you select [Yes] "+;
  1866. *--                          "you will delete this record.",cWind1,3)
  1867. *--               do case
  1868. *--                  case x = "O"
  1869. *--                       * do "OK" action
  1870. *--                  otherwise
  1871. *--                       *-- do "Cancel" action
  1872. *--               endcase
  1873. *-- Returns.....: Character (first char of button)
  1874. *-- Parameters..: nType    = Type of dialog box:
  1875. *--                          1 = Predefined: "OK  CANCEL"
  1876. *--                          2 = Predefined: "ABORT  RETRY  IGNORE"
  1877. *--                          3 = Predefined: "RETRY  CANCEL"
  1878. *--                           (For options with YES/NO or YES/NO/CANCEL,
  1879. *--                           see YESNO() or YNC(); for options with 
  1880. *--                           "OK", see ALERT())
  1881. *--                          4 = User-defined: Button text will depend
  1882. *--                              on text in cButton1,cButton2, and 
  1883. *--                              cButton3.
  1884. *--               nDefault = Which menu pad do you wish to default to?
  1885. *--                          Number refers to pad 1, 2 or 3.
  1886. *--               cWhere   = Where on the screen do you wish the dialog 
  1887. *--                          box to appear?
  1888. *--                          UL = Upper Left
  1889. *--                          UC = Upper Center
  1890. *--                          UR = Upper Right
  1891. *--                          CL = Center Left
  1892. *--                          CC = Center Center (default)
  1893. *--                          CR = Center Right
  1894. *--                          BL = Bottom Left
  1895. *--                          BC = Bottom Center
  1896. *--                          BR = Bottom Right
  1897. *--               cTitle   = Title for the title bar, up to 30 
  1898. *--                          characters
  1899. *--               cMessage = Message, up to 254 characters
  1900. *--               cColor   = Colors in standard foreground/background 
  1901. *--                          If no colors given, you will get the 
  1902. *--                          Borland "steel grey", with black text. 
  1903. *--                          The buttons and title bar will end up 
  1904. *--                          bright white on black.
  1905. *--               nStyle   = Border Style
  1906. *--                          1 = Double Border, raised (default)
  1907. *--                          2 = Double Border, recessed
  1908. *--                          3 = Single Border, raised
  1909. *--                          4 = Single Border, recessed
  1910. *--               cButton1 = Text for first button -- optional (only 
  1911. *--                          used if nType = 4) -- NOTE: Button text 
  1912. *--                          should be 6 char or less.
  1913. *--               cButton2 = Text for second button (as above)
  1914. *--               cButton3 = Text for third button (as above)
  1915. *-----------------------------------------------------------------------
  1916.  
  1917.    parameters nType, nDefault, cWhere, cTitle, cMessage, cColor, ;
  1918.               nStyle, cButton1, cButton2, cButton3
  1919.    private nParm,nWidth,nHeight,cRow,cCol,nTop,nBottom,nLeft,nRight,;
  1920.            cTempCol
  1921.    private nBordCol,nButtonRow,cWindow,cScreen,nScreen,nButtons
  1922.    
  1923.    *-- save current screen, save current window
  1924.    cWindow = window()
  1925.    save screen to sYesNo
  1926.    
  1927.    *-- determine # of parameters passed, and set defaults if necessary
  1928.    m->nParm = pcount()
  1929.  
  1930.    *-- deal with border
  1931.    if m->nParm < 7         && no selection for border-style, set to def.
  1932.       m->nStyle = 1
  1933.    endif
  1934.    if m->nStyle = 0
  1935.       m->nStyle = 1
  1936.    endif
  1937.    if m->nStyle < 1 .or. m->nStyle > 4  && don't screw with my routine!
  1938.       m->nStyle = 1
  1939.    endif
  1940.  
  1941.    *-- deal with colors
  1942.    if m->nParm < 6                   && no colors, set to steel-grey
  1943.       m->cColor = "N/W,W+/N,N/W"
  1944.    endif
  1945.    if isblank(m->cColor)
  1946.       m->cColor = "N/W,W+/N,N/W"
  1947.    endif
  1948.  
  1949.    *-- location on screen
  1950.    if isblank(m->cWhere)        && default location is center of screen
  1951.       m->cWhere = "CC"
  1952.    endif
  1953.    
  1954.    *-- deal with button types ...
  1955.    do case  && 1 space on either side of button ...
  1956.       case m->nType = 1
  1957.          m->nButtons = 2
  1958.          m->cButton1 = " OK "
  1959.          m->cButton2 = " Cancel "
  1960.          m->cButton3 = ""
  1961.       case m->nType = 2
  1962.          m->nButtons = 3
  1963.          m->cButton1 = " Abort "
  1964.          m->cButton2 = " Retry "
  1965.          m->cButton3 = " Ignore "
  1966.       case m->nType = 3
  1967.          m->nButtons = 2
  1968.          m->cButton1 = " Retry "
  1969.          m->cButton2 = " Cancel "
  1970.       case m->nType = 4 .and. m->nParm > 8  
  1971.                                  && must be two buttons or more
  1972.          m->nButtons = m->nParm - 7
  1973.          m->cButton1 = " "+ltrim(rtrim(m->cButton1))+" "
  1974.          m->cButton2 = " "+lTrim(rTrim(m->cButton2))+" "
  1975.          if m->nButtons > 2
  1976.             m->cButton3 = " "+lTrim(rTrim(m->cButton3))+" "
  1977.          endif
  1978.       otherwise
  1979.          RETURN "ERROR!"
  1980.    endcase
  1981.    
  1982.    *-- just to be sure ...
  1983.    if m->nDefault = 0 .or. m->nDefault > m->nButtons
  1984.       m->nDefault = 1
  1985.    endif
  1986.    
  1987.    *-- set some defaults
  1988.    m->nWidth = 36 + iif(m->nStyle < 3,4,2)    && width of dialog box
  1989.    
  1990.    *-- determine height of window by text
  1991.    *-- if the remainder of the length of the message/width is > 0
  1992.    *--    we have one more line of text, add 1, else add 0
  1993.    *-- border will determine more ... (if it's 1 or 2, it's double-size,
  1994.    *--    so we add 4 lines (top/bottom * 2), if it's 3 or 4, it's 
  1995.    *--    single ...)
  1996.    *-- add 2 rows for the title, and 3 for the menu, and 1 for the 
  1997.    *-- button borders ...
  1998.    m->nHeight = int(len(m->cMessage)/m->nWidth) + ;
  1999.              iif(mod(len(m->cMessage),m->nWidth) > 0,1,0) +;
  2000.              iif(m->nStyle < 3,3,1) +  6
  2001.    
  2002.    *-- now to determine window Coordinates
  2003.    m->cRow = left(m->cWhere,1)
  2004.    m->cCol = right(m->cWhere,1)
  2005.    
  2006.    *-- get screen height
  2007.    m->cScreen = SET("DISPLAY")
  2008.    if m->cScreen = "MONO"
  2009.       m->nScreen = 24
  2010.    else
  2011.       m->nScreen = val(right(m->cScreen,2)) - 1  && (EGA25 = 0 to 24)
  2012.    endif
  2013.    
  2014.    *-- this is where we _really_ determine the coordinates
  2015.    do case   && first let's get the rows (top/bottom)
  2016.       case m->cRow = "U"
  2017.          m->nTop = 1
  2018.       case m->cRow ="B"
  2019.          m->nTop = (m->nScreen - m->nHeight - 2)  
  2020.       otherwise  && "C" or center ...
  2021.          m->nTop = (m->nScreen - m->nHeight) / 2
  2022.    endcase
  2023.    m->nBottom = m->nTop + m->nHeight
  2024.    
  2025.    do case   && now for the columns
  2026.       case m->cCol = "L"
  2027.          m->nLeft = 5
  2028.       case m->cCol = "R"
  2029.          m->nLeft = 35
  2030.       otherwise && "C" or center
  2031.          m->nLeft = 20
  2032.    endcase
  2033.    m->nRight = m->nLeft + m->nWidth
  2034.    
  2035.    *-- define window
  2036.    activate screen
  2037.    define window wYesNo from m->nTop,m->nLeft to m->nBottom,m->nRight;
  2038.                                                     NONE color &cColor.
  2039.    
  2040.    *-- define menu
  2041.    define menu mYesNo
  2042.    m->nButtonRow = m->nHeight - iif(m->nStyle<3,3,2)
  2043.    m->nB1 = 5                        && column for first  button
  2044.    if m->nButtons = 3
  2045.       m->nB2 = (m->nWidth-len(m->cButton2))/2  && column for 2nd button
  2046.    else
  2047.       m->nB2 = (m->nWidth-len(m->cButton2))-4
  2048.    endif
  2049.    if m->nButtons > 2
  2050.       m->nB3 = (m->nWidth-len(m->cButton3))-4  && column for 3rd button
  2051.    endif
  2052.    define pad pPad1 of mYesNo prompt m->cButton1 at m->nButtonRow,m->nB1
  2053.    define pad pPad2 of mYesNo prompt m->cButton2 at m->nButtonRow,m->nB2
  2054.    if m->nButtons > 2
  2055.       define pad pPad3 of mYesNo prompt m->cButton3 at ;
  2056.                                                     m->nButtonRow,m->nB3
  2057.    endif
  2058.    on selection pad pPad1 of mYesNo deactivate menu
  2059.    on selection pad pPad2 of mYesNo deactivate menu
  2060.    if m->nButtons > 2
  2061.       on selection pad pPad3 of mYesNo deactivate menu
  2062.    endif
  2063.    
  2064.    *-- activate window
  2065.    do shadow with m->nTop,m->nLeft,m->nBottom,m->nRight
  2066.    activate window wYesNo
  2067.    
  2068.    *-- draw border
  2069.    m->cBordCol = left(m->cColor,at(",",m->cColor)-1)
  2070.    do bord3d with 0,0,m->nHeight,m->nWidth,m->cBordCol,m->nStyle 
  2071.    
  2072.    *-- display title
  2073.    if len(m->cTitle) < m->nWidth
  2074.       m->cTitle = justify(m->cTitle,35,"C")
  2075.       if len(m->cTitle) < 35
  2076.          m->cTitle = m->cTitle + " "
  2077.       endif
  2078.    endif
  2079.    m->cTempCol = colorbrk(m->cColor,2)
  2080.    m->cColorF  = FBClrBrk("B",m->cTempCol)
  2081.    m->cColorB  = FBClrBrk("B",colorbrk(m->cColor,1))
  2082.    m->cColorAll= m->cColorF+"/"+m->cColorB
  2083.    m->nRow = iif(m->nStyle < 3,2,1)
  2084.    m->nCol = iif(m->nStyle < 3,3,2)
  2085.    @m->nRow,  m->nCol say m->cTitle color &cTempCol.
  2086.    @m->nRow+1,m->nCol say replicate(chr(223),35) color &cColorAll.
  2087.    
  2088.    *-- display text
  2089.    do WordWrap with iif(m->nStyle<3,4,3),iif(m->nStyle<3,4,3),;
  2090.                     m->cMessage,34
  2091.    
  2092.    *-- set Y/N keys for menu pad
  2093.    clear typeahead && just to be safe
  2094.    *-- if we're ON the pad user selected, do nothing, else go left or
  2095.    *-- right as needed, and then issue a "Return" (chr(13))
  2096.    m->cKey1 = substr(m->cButton1,2,1)
  2097.    m->cKey2 = substr(m->cButton2,2,1)
  2098.    if m->nButtons > 2
  2099.       m->cKey3 = substr(m->cButton3,2,1)
  2100.    endif
  2101.    if m->nButtons > 2
  2102.       on key label &cKey1. keyboard iif(pad() = "PPAD1","",;
  2103.          iif(pad()="PPAD2",chr(19),chr(4) ) )+chr(13)
  2104.       on key label &cKey2. keyboard iif(pad() = "PPAD2" ,"",;
  2105.          iif(pad()="PPAD1",chr(4),chr(19) ) )+chr(13)
  2106.       on key label &cKey3. keyboard iif(pad() = "PPAD3","",;
  2107.          iif(pad()="PPAD2",chr(4),chr(19) ) )+chr(13)
  2108.    else
  2109.       on key label &cKey1. keyboard iif(pad() = "PPAD1",;
  2110.                                chr(19),chr(4))+chr(13)
  2111.       on key label &cKey2. keyboard iif(pad() = "PPAD2",;
  2112.                                chr(4),chr(19))+chr(13)
  2113.    endif
  2114.    
  2115.    *-- deal with borders around the pads ...
  2116.    do bord3d with m->nButtonRow-1,m->nB1-1,m->nButtonRow+1,;
  2117.                   m->nB1+len(m->cButton1),m->cBordCol,3
  2118.    do bord3d with m->nButtonRow-1,m->nB2-1, m->nButtonRow+1,;
  2119.                   m->nB2+len(m->cButton2),m->cBordCol,3
  2120.    if m->nButtons > 2
  2121.       do bord3d with m->nButtonRow-1,m->nB3-1,m->nButtonRow+1,;
  2122.                   m->nB3+len(m->cButton3),m->cBordCol,3
  2123.    endif
  2124.    
  2125.    *-- activate menu
  2126.    do case
  2127.       case m->nDefault = 1
  2128.          activate menu mYesNo pad pPad1
  2129.       case m->nDefault = 2
  2130.          activate menu mYesNo pad pPad2
  2131.       case m->nDefault = 3
  2132.          activate menu mYesNo pad pPad3
  2133.       otherwise  && default to first
  2134.          activate menu mYesNo pad pPad1
  2135.    endcase
  2136.    
  2137.    *-- cleanup
  2138.    on key label &cKey1.
  2139.    on key label &cKey2.
  2140.    if m->nButtons > 2
  2141.       on key label &cKey3.
  2142.    endif
  2143.    release window wYesNo
  2144.    restore screen from sYesNo
  2145.    release screen sYesNo
  2146.    m->cPrompt = prompt()
  2147.    release menu mYesNo
  2148.    if .not. isblank(cWindow)
  2149.       activate window &cWindow.
  2150.    endif
  2151.          
  2152. RETURN substr(m->cPrompt,2,1)
  2153. *-- EoF: DIALOG2()
  2154.  
  2155. FUNCTION ErrorMsg
  2156. *-----------------------------------------------------------------------
  2157. *-- Programmer..: Ken Mayer (CIS: 71333,1030)
  2158. *-- Date........: 06/08/1992
  2159. *-- Notes.......: Display an error message in a Window: 
  2160. *--                           ** ERROR [#] **
  2161. *--
  2162. *--                              Message 1
  2163. *--                              Message 2
  2164. *--                       Press any key to continue ...
  2165. *-- Written for.: dBASE IV, 1.1
  2166. *-- Rev. History: 06/08/1992 -- Modified for explicit color handing.
  2167. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  2168. *--               CENTER               Procedure in PROC.PRG
  2169. *--               ALLTRIM()            Function in PROC.PRG
  2170. *-- Called by...: Any
  2171. *-- Usage.......: ErrorMsg("<cErr>","<cMess1>","<cMess2>","<cColor>")
  2172. *-- Example.....: lc_Dummy = errormsg("3","This record",;
  2173. *--                                   "already exists!",;
  2174. *--                                   "rg+/r,rg+/r,rg+/r")
  2175. *--               where "errornum" is an error number or nul,
  2176. *--               message2 and 3 should be 36 characters or less ...
  2177. *--               Colors should include foreground/background,;
  2178. *--                 foreground/background,foreground/background
  2179. *-- Returns.....: numeric value of keystroke user presses (cUser)
  2180. *-- Parameters..: cErr   = Error # (can be blank, but use "" for blank)
  2181. *--               cMess1 = Error message line 1
  2182. *--               cMess2 = Error message line 2
  2183. *--               cColor = Colors for text/window/border
  2184. *-----------------------------------------------------------------------
  2185.    
  2186.    parameters cErr,cMess1,cMess2,cColor
  2187.    private cCursor,cUser,cCurColor,cTempCol
  2188.    
  2189.    save screen to sErr
  2190.    activate screen
  2191.    define window wErr from 8,20 to 15,60 double color &cColor.
  2192.    do shadow with 8,20,15,60
  2193.    activate window wErr
  2194.    
  2195.    m->cCursor = set("CURSOR")
  2196.    set cursor off
  2197.    if len(trim(m->cErr)) > 0  && if there's an error number ...
  2198.       do center with 0,38,"","** ERROR "+alltrim(m->cErr)+" **"
  2199.    else                      && otherwise, don't display errornumber
  2200.       do center with 0,38,"","** ERROR **"
  2201.    endif
  2202.    do center with 2,38,"",m->cMess1
  2203.    do center with 3,38,"",m->cMess2
  2204.    do center with 5,38,"","Press any key to continue ..."
  2205.    m->cUser=inkey(0)
  2206.    
  2207.    set cursor &cCursor.
  2208.    release window wErr
  2209.    restore screen from sErr
  2210.    release screen sErr
  2211.    
  2212. RETURN m->cUser
  2213. *-- EoF: ErrorMsg()
  2214.  
  2215. FUNCTION ErrorMsg2
  2216. *-----------------------------------------------------------------------
  2217. *-- Programmer..: Ken Mayer (CIS: 71333,1030)
  2218. *-- Date........: 03/18/1993
  2219. *-- Notes.......: Display an error message in a Window: 
  2220. *--                           ** ERROR [#] **
  2221. *--
  2222. *--                              Message 1
  2223. *--                              Message 2
  2224. *--
  2225. *--                       Press any key to continue ...
  2226. *--
  2227. *--               WARNING: This version produces a dialog box that is 
  2228. *--               two rows taller and two columns wider than previous. 
  2229. *-- Written for.: dBASE IV, 1.5
  2230. *-- Rev. History: 06/08/1992 -- Original
  2231. *--               03/18/1993 -- Modified to give the three-d border ...
  2232. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  2233. *--               CENTER               Procedure in PROC.PRG
  2234. *--               ALLTRIM()            Function in PROC.PRG
  2235. *--               BORD3D               Procedure in PROC.PRG
  2236. *-- Called by...: Any
  2237. *-- Usage.......: ErrorMsg2("<cErr>","<cMess1>","<cMess2>","<cColor>";
  2238. *--                         [,<nStyle>])
  2239. *-- Example.....: cDummy = errormsg2("3","This record",;
  2240. *--                                  "already exists!",;
  2241. *--                                  "rg+/r,rg+/r,rg+/r",2)
  2242. *--               where "errornum" is an error number or nul,
  2243. *--               message2 and 3 should be 36 characters or less ...
  2244. *--               Colors should include foreground/background,;
  2245. *--                 foreground/background,foreground/background
  2246. *-- Returns.....: numeric value of keystroke user presses (cUser)
  2247. *-- Parameters..: cErr   = Error # (can be blank, but use "" for blank)
  2248. *--               cMess1 = Error message line 1
  2249. *--               cMess2 = Error message line 2
  2250. *--               cColor = Colors for text/window/border
  2251. *--               nStyle = OPTIONAL - style -- 1 = Raised, 2 = Recessed
  2252. *-----------------------------------------------------------------------
  2253.    
  2254.    parameters cErr,cMess1,cMess2,cColor,nStyle
  2255.    private cCursor,cUser,cCurColor,cTempCol
  2256.    
  2257.    if pCount() < 5
  2258.       m->nStyle = 1
  2259.    endif
  2260.    
  2261.    save screen to sErr
  2262.    activate screen
  2263.    define window wErr from 7,19 to 16,61 NONE color &cColor.
  2264.    do shadow with 7,19,16,61
  2265.    activate window wErr
  2266.    
  2267.    *-- do border
  2268.    do Bord3d with 9,42,m->cColor,m->nStyle
  2269.    
  2270.    m->cCursor = set("CURSOR")
  2271.    set cursor off
  2272.    if len(trim(m->cErr)) > 0  && if there's an error number ...
  2273.       do center with 2,42,"","** ERROR "+alltrim(m->cErr)+" **"
  2274.    else                      && otherwise, don't display errornumber
  2275.       do center with 2,42,"","** ERROR **"
  2276.    endif
  2277.    do center with 4,42,"",left(m->cMess1,38)
  2278.    do center with 5,42,"",left(m->cMess2,38)
  2279.    do center with 7,42,"","Press any key to continue ..."
  2280.    m->cUser=inkey(0)
  2281.    
  2282.    set cursor &cCursor.
  2283.    release window wErr
  2284.    restore screen from sErr
  2285.    release screen sErr
  2286.    
  2287. RETURN m->cUser
  2288. *-- EoF: ErrorMsg2()
  2289.  
  2290. FUNCTION ErrorMsg3
  2291. *-----------------------------------------------------------------------
  2292. *-- Programmer..: Ken Mayer (CIS: 71333,1030)
  2293. *-- Date........: 06/11/1993
  2294. *-- Notes.......: Display an error message in a Window: 
  2295. *--                           ** ERROR [#] **
  2296. *--
  2297. *--                       Message (wraps in window)
  2298. *--
  2299. *--                                 [OK]               
  2300. *--
  2301. *-- Written for.: dBASE IV, 1.5
  2302. *-- Rev. History: 06/08/1992 -- Original
  2303. *--               03/18/1993 -- Modified to give the three-d border ...
  2304. *--               06/10/1993 -- Modified to give 4 options to border,
  2305. *--                             default color of grey/black/white,
  2306. *--                             handle single message of up to 254 
  2307. *--                             characters.
  2308. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  2309. *--               CENTER               Procedure in PROC.PRG
  2310. *--               ALLTRIM()            Function in PROC.PRG
  2311. *--               WORDWRAP             Procedure in PROC.PRG
  2312. *--               BORD3D5              Procedure in DIALOGS.PRG
  2313. *-- Called by...: Any
  2314. *-- Usage.......: ErrorMsg3(<cErr>,<cMess>[,<cColor>[,<nStyle>]])
  2315. *-- Example.....: cDummy = errormsg3("3","This record already exists!",;
  2316. *--                   "rg+/r,rg+/r,rg+/r",2)
  2317. *-- Returns.....: numeric value of keystroke user presses (cUser)
  2318. *-- Parameters..: cErr   = Error # (can be blank, but use "" for blank)
  2319. *--               cMess  = Error message -- up to 254 characters
  2320. *--               cColor = Colors for text/window/border (default to 
  2321. *--                        grey)
  2322. *--               nStyle = 1 = Double - Raised
  2323. *--                        2 = Double - Recessed
  2324. *--                        3 = Single - Raised
  2325. *--                        4 = Single - Recessed
  2326. *-----------------------------------------------------------------------
  2327.    
  2328.    parameters cErr,cMess,cColor,nStyle
  2329.    private cCursor,cUser,cCurColor,cTempCol
  2330.    
  2331.    *-- defaults
  2332.    if pCount() < 4 .or. (m->nStyle < 1 .or. m->nStyle > 4)
  2333.       m->nStyle = 1
  2334.    endif
  2335.    if pCount() < 3
  2336.       m->cColor = "n/w,w+/n,n/w"
  2337.    endif
  2338.    if isblank(m->cColor)
  2339.       m->cColor = "n/w,w+/n,n/w"
  2340.    endif
  2341.    
  2342.    *-- screen stuff
  2343.    save screen to sErr
  2344.    cWindow = window()
  2345.    activate screen
  2346.    
  2347.    *-- determine coordinates
  2348.    *-- width is a default of 36 characters, plus border ...
  2349.    m->nWidth = 36 + iif(m->nStyle < 3, 4, 2)  && based on border style
  2350.    
  2351.    *-- height is based on lines in message
  2352.    m->nHeight = int(len(m->cMess)/m->nWidth) +;
  2353.              iif( mod( len(m->cMess), m->nWidth) > 0,1,0) +;
  2354.              iif(m->nStyle < 3,3,1) + 6
  2355.    
  2356.    *-- now we have height and width, let's determine how to center this
  2357.    *-- puppy on the screen
  2358.    m->cScreen = set("DISPLAY")
  2359.    if m->cScreen = "MONO"
  2360.       m->nScreen = 24
  2361.    else
  2362.       m->nScreen = val(right(m->cScreen,2)) - 1
  2363.    endif
  2364.    
  2365.    *-- coordinates
  2366.    m->nTop    = (m->nScreen-m->nHeight) / 2
  2367.    m->nBottom = m->nTop + m->nHeight
  2368.    m->nLeft   = 20
  2369.    m->nRight  = m->nLeft + m->nWidth
  2370.    
  2371.    *-- define the window
  2372.    define window wErr from m->nTop,m->nLeft to m->nBottom,m->nRight ;
  2373.                                                    NONE color &cColor.
  2374.    do shadow with m->nTop,m->nLeft,m->nBottom,m->nRight
  2375.    activate window wErr
  2376.    
  2377.    *-- do border
  2378.    m->cBordCol = colorbrk(m->cColor,1)
  2379.    do Bord3d5 with 0,0,(m->nBottom-m->nTop),m->nWidth,m->cBordCol,;
  2380.                                                       m->nStyle
  2381.    
  2382.    m->cCursor = set("CURSOR")
  2383.    set cursor off
  2384.    
  2385.    *-- deal with "title" line
  2386.    if len(trim(m->cErr)) > 0  && if there's an error number ...
  2387.       m->cTitle = "** ERROR "+alltrim(m->cErr)+" **"
  2388.    else                      && otherwise, don't display errornumber
  2389.       m->cTitle = "** ERROR **"
  2390.    endif
  2391.    m->cTitle = justify(m->cTitle,35,"C")
  2392.    if len(m->cTitle) < 35
  2393.       m->cTitle = m->cTitle + " "
  2394.    endif
  2395.    m->cTempCol = colorbrk(m->cColor,2)
  2396.    m->cColorF  = fbclrbrk("B",m->cTempCol)
  2397.    m->cColorB  = fbclrbrk("B",colorbrk(m->cColor,1))
  2398.    m->cColorAll = m->cColorF+"/"+m->cColorB
  2399.    m->nRow = iif(m->nStyle<3,2,1)
  2400.    m->nCol = iif(m->nStyle<3,3,2)
  2401.    @m->nRow,m->nCol say m->cTitle color &cTempCol.
  2402.    @m->nRow+1,m->nCol say replicate(chr(223),35) color &cColorAll.
  2403.    
  2404.    *-- display message
  2405.    do wordwrap with iif(m->nStyle<3,4,3),iif(m->nStyle<3,4,3),;
  2406.                     m->cMess,34
  2407.    
  2408.    *-- define menu ...
  2409.    define menu mError
  2410.    m->nButtonRow = m->nHeight - iif(m->nStyle<3,3,2)
  2411.    m->nButtonCol = m->nWidth/2 - 1
  2412.    define pad pPad1 of mError prompt "[OK]" at ;
  2413.                                     m->nButtonRow,m->nButtonCol
  2414.    on selection pad pPad1 of mError deactivate menu
  2415.    on key label ctrl-M keyboard "{27}"
  2416.    do bord3d5 with m->nButtonRow-1,m->nButtonCol-1,m->nButtonRow+1,;
  2417.                                    m->nButtonCol+4,m->cBordCol,3
  2418.    
  2419.    *-- start menu
  2420.    activate menu mError
  2421.    
  2422.    *-- deal with user 'input'
  2423.    mPad = pad()
  2424.    
  2425.    *-- reset and cleanup
  2426.    set cursor &cCursor.
  2427.    release window wErr
  2428.    restore screen from sErr
  2429.    release screen sErr
  2430.    release menu mError
  2431.    on key label ctrl-M
  2432.    if "" # cWindow
  2433.       activate window &cWindow.
  2434.    endif
  2435.    
  2436. RETURN .not. "" = mPad  && empty pad?
  2437. *-- EoF: ErrorMsg3()
  2438.  
  2439. FUNCTION Alert
  2440. *-----------------------------------------------------------------------
  2441. *-- Programmer..: Adam L. Menkes (BORLAND TECHNICAL SUPPORT)
  2442. *-- Date........: 06/19/1992
  2443. *-- Notes.......: This routine creates a popup on the screen with a 
  2444. *--               title and one line message, forcing the user to notice
  2445. *--               the message. The user must use the mouse on the 'OK'
  2446. *--               pad, press <Esc> or press <Enter> to move on in the 
  2447. *--               program that called this function.
  2448. *-- Written for.: dBASE IV, 1.5
  2449. *-- Rev. History: 06/01/1992 -- Original
  2450. *--               06/19/1992 - Modified to accept the <Enter> key by
  2451. *--               Ken Mayer, also a bit better cleanup at the end 
  2452. *--               (releasing things from memory, and so on).
  2453. *-- Calls.......: None
  2454. *-- Called by...: Any
  2455. *-- Usage.......: Alert("<cTitle>","<cMessage>")
  2456. *-- Example.....: lX = Alert("Print Aborted","You pressed <ESC>")
  2457. *-- Returns.....: Logical
  2458. *-- Parameters..: cTitle   = Title line
  2459. *--               cMessage = One line message (up to 79 characters)
  2460. *-----------------------------------------------------------------------
  2461.  
  2462.    parameters cTitle, cMessage
  2463.    private wWindow,nRow,nCol,mPad
  2464.    
  2465.    wWindow = WINDOW()                  && save current Window
  2466.    save screen to sTemp                && save the screen
  2467.         activate screen
  2468.    
  2469.    m->nRow = iif(val(right(set("DISPLAY"),2)) = 43,18,8)  
  2470.                                        && center from top-bottom
  2471.    m->nCol = 38 - (max(len(m->cTitle),len(m->cMessage))/2)      
  2472.                                        && center left-right
  2473.    m->nCol2 = max(len(m->cTitle),len(m->cMessage))  
  2474.                                        && right side
  2475.    
  2476.    *-- clear out a section of the screen
  2477.    @m->nRow,m->nCol Clear to m->nRow+6,m->nCol+m->nCol2
  2478.    *-- fill in a box
  2479.    @m->nRow,m->nCol Fill  to m->nRow+6,m->nCol+m->nCol2+1 color n+  
  2480.                                         && grey
  2481.    *-- put a double line border around box
  2482.    @m->nRow,m->nCol to m->nRow+6,m->nCol+m->nCol2+1 double color bg+
  2483.  
  2484.    *-- display title
  2485.    @m->nRow + 1,m->nCol + 1 + iif(len(m->cTitle) > len(m->cMessage),0,;
  2486.       (len(m->cMessage)-len(m->cTitle)) / 2) say m->cTitle color w+/n
  2487.  
  2488.    *-- display line
  2489.    @m->nRow + 2, m->nCol + 1 to m->nRow + 2, m->nCol + m->nCol2 ;
  2490.                                                        color bg+
  2491.  
  2492.    *-- display message
  2493.    @m->nRow + 3, m->nCol+1+iif(len(m->cTitle) > len(m->cMessage),;
  2494.       (len(m->cTitle)-len(m->cMessage)) / 2, 0) say m->cMessage ;
  2495.                                                   color w+/n
  2496.    
  2497.    *-- define/display a very small menu (one pad)
  2498.    define menu mAlert
  2499.    define pad pPad1 of mAlert prompt " OK " at m->nRow +5,37
  2500.    on selection pad pPad1 of mAlert deactivate menu
  2501.    
  2502.    *-- added by Ken to deal with <Enter>
  2503.    on key label ctrl-M keyboard "{27}"
  2504.    
  2505.    *-- start it up
  2506.    activate menu mAlert
  2507.    
  2508.    *-- deal with user 'input'
  2509.    mPad = pad()
  2510.    
  2511.    *-- restore environment, free up RAM by releasing things
  2512.    on key label ctrl-m
  2513.    restore screen from sTemp
  2514.    release screen sTemp
  2515.    release menu mAlert
  2516.    if "" # wWindow
  2517.       activate window &wWindow.
  2518.    endif
  2519.    
  2520. RETURN .not. "" = mPad  && not empty pad?
  2521. *-- EoF: Alert()
  2522.  
  2523. FUNCTION Alert2
  2524. *-----------------------------------------------------------------------
  2525. *-- Programmer..: Adam L. Menkes (SUPREME1)
  2526. *-- Date........: 11/16/1992
  2527. *-- Notes.......: This function based on Alert2()
  2528. *--               This routine creates a popup on the screen with a 
  2529. *--               title and one line message, forcing the user to 
  2530. *--               notice the message. The user must use the mouse on 
  2531. *--               the 'OK' pad, press <Esc> or press <Enter> to move 
  2532. *--               on in the program that called this function.
  2533. *-- Written for.: dBASE IV, 1.5
  2534. *-- Rev. History: 06/01/1992 -- Original 
  2535. *--               Modified to accept the <Enter> key by Ken Mayer.
  2536. *--               06/19/1992 -- Copied from Adam's original, uses a 
  2537. *--                 window, shadow, and programmer defineable colors.
  2538. *--               07/29/1992 -- Joey stepped in and made some 
  2539. *--                  modifications that seem to have helped as well, 
  2540. *--                  including dealing with the keyboard buffer.
  2541. *--               10/09/1992 -- minor change -- title is now same color
  2542. *--                  as the "pad".
  2543. *--               11/12/1992 -- changed to look more like a Win 3.0/3.1
  2544. *--                 window by printing a special 'line' below the title.
  2545. *--                 Also removed hard coding which forced border to 
  2546. *--                 DOUBLE so that if called with border set to NONE, 
  2547. *--                 gives even more Win-like appearance.  Calls a new 
  2548. *--                 function written for this technique, but can be used
  2549. *--                 in other programs.
  2550. *--               11/16/1992 -- modified to add cBORDER parameter ... 
  2551. *--                 (K. Mayer)
  2552. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  2553. *--               CENTER               Procedure in PROC.PRG
  2554. *--               JUSTIFY()            Function in PROC.PRG
  2555. *--               COLORBRK()           Function in PROC.PRG
  2556. *--               FBCLRBRK()           Function in PROC.PRG 
  2557. *-- Called by...: Any
  2558. *-- Usage.......: Alert2("<cTitle>","<cMessage>","<cColor>"[,;
  2559. *--                      "<cBorder>"])
  2560. *-- Example.....: ** if no border, I suggest colors which will contrast
  2561. *--                  with the active screen or window
  2562. *--               lX = Alert2("Print Aborted","You pressed <ESC>",;
  2563. *--                           "rg+/r,w+/b,rg+/r","NONE")
  2564. *-- Returns.....: Logical
  2565. *-- Parameters..: cTitle   = Title line
  2566. *--               cMessage = One line message (up to 75 characters)
  2567. *--               cColor   = Colors: <window forg/back>,<pad> (and 
  2568. *--                                  title),<box>
  2569. *--               cBorder  = Border type (DOUBLE, SINGLE, NONE, 
  2570. *--                           PANEL) -- optional -- will default to 
  2571. *--                           your setting 
  2572. *-----------------------------------------------------------------------
  2573.  
  2574.    parameters cTitle, cMessage, cColor, cBorder
  2575.    private wWindow,nRow,nCol,mPad,cTempCol,cColorF,cColorB,cColorAll,;
  2576.            lNoBorder
  2577.  
  2578.    wWindow = WINDOW()                  && save current Window
  2579.    save screen to sTemp                && save the screen
  2580.    activate screen
  2581.    m->cDummykey = inkey()              && clear out keyboard buffer
  2582.    m->cOldBorder = set("BORDER")       && get old border setting
  2583.    if .not. type("m->cBorder") = "L"   && if user set border ...
  2584.       set border to &cBorder.          && start NEW border setting
  2585.    endif
  2586.    m->lNoBorder = set("BORDER") = "NONE"  && is there a border?
  2587.  
  2588.    *-- get window coordinates
  2589.    *-- this centers from top to bottom, depending on monitor setup ...
  2590.    m->nULRow = iif(val(right(set("DISPLAY"),2)) = 43,18,8)
  2591.    *-- add rows, number depends on border, so the Window is large 
  2592.    *-- enough ...
  2593.    if m->lNoBorder
  2594.       m->nBRRow = m->nULRow + 4
  2595.    else
  2596.       m->nBRRow = m->nULRow + 6
  2597.    endif
  2598.    *-- left column ...
  2599.    m->nULCol = 36 - (max(len(m->cTitle),len(m->cMessage))/2)    
  2600.                                         && center left-right
  2601.    *-- right column ...
  2602.    m->nBRCol = m->nULCol + max(len(m->cTitle),len(m->cMessage))+4  
  2603.                                         && right side?
  2604.    *-- Window width ...
  2605.    m->nWidth = m->nBRCol - m->nULCol - 1
  2606.  
  2607.    *-- define window
  2608.    activate screen
  2609.  
  2610.    Define window wAlert from m->nULRow,m->nULCol to m->nBRRow,m->nBRCol;
  2611.                                                     color &cColor.
  2612.  
  2613.    *-- display shadow
  2614.    do shadow with m->nULRow,m->nULCol,m->nBRRow,m->nBRCol
  2615.  
  2616.    *-- start 'er up ...
  2617.    activate window wAlert
  2618.  
  2619.    *-- display title
  2620.    m->cTempCol = colorbrk(m->cColor,2)
  2621.    if len(m->cTitle) < m->nWidth
  2622.        m->cTitle = justify(m->cTitle,iif(m->lNoBorder,m->nWidth+2,;
  2623.                            m->nWidth),"C")
  2624.        if len(m->cTitle) < m->nWidth
  2625.           m->cTitle = m->cTitle + " "
  2626.        endif
  2627.    endif
  2628.  
  2629.    *-- display  a new type type line to look more like Win
  2630.    m->cColorF   = FBClrBrk("B",m->cTempCol)
  2631.    m->cColorB   = FBClrBrk("B",colorbrk(m->cColor,1))
  2632.    m->cColorAll = m->cColorF + "/" + m->cColorB
  2633.    if m->lNoBorder
  2634.      do center with 0,m->nWidth + 3,m->cTempCol,m->cTitle
  2635.      *-- chr(223) looks like this --> ï¬‚ <--
  2636.      @ 1,0 say replicate(chr(223),m->nWidth + 2) color &cColorAll.
  2637.    else
  2638.      do center with 0,m->nWidth,m->cTempCol,m->cTitle
  2639.      @ 1,0 say replicate(chr(223),m->nWidth) color &cColorAll.
  2640.    endif
  2641.  
  2642.    *-- display message
  2643.    do center with 2,m->nWidth,"",m->cMessage
  2644.  
  2645.    *-- define/display a very small menu (one pad)
  2646.    define menu mAlert
  2647.    define pad pPad1 of mAlert prompt "[OK]" at 4,(m->nWidth/2-2)
  2648.    on selection pad pPad1 of mAlert deactivate menu
  2649.  
  2650.    *-- added by Ken to deal with <Enter>
  2651.    on key label ctrl-M keyboard "{27}"
  2652.  
  2653.    *-- start it up
  2654.    activate menu mAlert
  2655.  
  2656.    *-- deal with user 'input'
  2657.    mPad = pad()
  2658.    release window wAlert
  2659.  
  2660.    *-- restore environment, free up RAM by releasing things
  2661.    on key label ctrl-m
  2662.    restore screen from sTemp
  2663.    release screen sTemp
  2664.    release menu mAlert
  2665.    if "" # wWindow
  2666.        activate window &wWindow.
  2667.    endif
  2668.    set border to &cOldBorder.
  2669.    
  2670. RETURN .not. "" = mPad  && not empty pad?
  2671. *-- EoF: Alert2()
  2672.  
  2673. FUNCTION Alert3
  2674. *-----------------------------------------------------------------------
  2675. *-- Programmer..: Adam L. Menkes (SUPREME1)
  2676. *-- Date........: 12/23/1992
  2677. *-- Notes.......: This function based on Alert2()
  2678. *--               This routine creates a popup on the screen with a 
  2679. *--               title and one line message, forcing the user to 
  2680. *--               notice the message. The user must use the mouse on 
  2681. *--               the 'OK' pad, press <Esc> or press <Enter> to move 
  2682. *--               on in the program that called this function.
  2683. *-- Written for.: dBASE IV, 1.5
  2684. *-- Rev. History: 06/19/1992 - Original
  2685. *--               Modified to accept the <Enter> key by Ken Mayer.
  2686. *--               06/19/1992 -- Copied from Adam's original, uses a 
  2687. *--                 window, shadow, and programmer defineable colors.
  2688. *--               07/29/1992 -- Joey stepped in and made some 
  2689. *--                 modifications that seem to have helped as well, 
  2690. *--                 including dealing with the keyboard buffer.
  2691. *--               10/09/1992 -- minor change -- title is now same color 
  2692. *--                 as the "pad".
  2693. *--               11/12/1992 -- changed to look more like a Win 3.0/3.1
  2694. *--                 window by printing a special 'line' below the title.
  2695. *--                 Also removed hard coding which forced border to 
  2696. *--                 DOUBLE so that if called with border set to NONE, 
  2697. *--                 gives even more Win-like appearance.  Calls a new
  2698. *--                 function written for this technique, but can be 
  2699. *--                 used in other programs.
  2700. *--               11/16/1992 -- modified to add cBORDER parameter ... 
  2701. *--                 (K. Mayer)
  2702. *--               12/23/1992 -- tuned up centering of cTitle, cMessage, 
  2703. *--                  and [OK] pad.  Eliminated calls to Center.prg by 
  2704. *--                  using Justify() along with @ say. (Joey D. Carroll)
  2705. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  2706. *--               JUSTIFY()            Function in PROC.PRG
  2707. *--               COLORBRK()           Function in PROC.PRG
  2708. *--               FBCLRBRK()           Function in PROC.PRG 
  2709. *-- Called by...: Any
  2710. *-- Usage.......: Alert2("<cTitle>","<cMessage>","<cColor>"[,;
  2711. *--                      "<cBorder>"])
  2712. *-- Example.....: ** if no border, I suggest colors which will contrast
  2713. *--                  with the active screen or window
  2714. *--               lX = Alert2("Print Aborted","You pressed <ESC>",;
  2715. *--                           "rg+/r,w+/b,rg+/r","NONE")
  2716. *-- Returns.....: Logical
  2717. *-- Parameters..: cTitle   = Title line
  2718. *--               cMessage = One line message (up to 75 characters)
  2719. *--               cColor   = Colors: <window forg/back>,<pad> (and 
  2720. *--                                  title),<box>
  2721. *--               cBorder  = Border type (DOUBLE, SINGLE, NONE, PANEL) 
  2722. *--                          optional -- will default to your setting
  2723. *-----------------------------------------------------------------------
  2724.  
  2725.    parameters cTitle, cMessage, cColor, cBorder
  2726.    private wWindow,mPad,cTempCol,cColorF,cColorB,cColorAll
  2727.    private nWidth,nULRow,m->nULCol,nLRRow,nLRCol,cTitle2,cMessage2,;
  2728.            nBorder
  2729.  
  2730.    m->cTitle2 = " " + ltrim(trim(m->cTitle)) + " "      
  2731.                                   && don't jamb against walls
  2732.    m->cMessage2 = " " + ltrim(trim(m->cMessage)) + " "  
  2733.                                   && don't jamb against walls
  2734.    wWindow = WINDOW()             && save current Window
  2735.    save screen to sTemp           && save the screen
  2736.    activate screen
  2737.    m->cDummykey = inkey()         && clear out keyboard buffer
  2738.    m->cOldBorder = set("BORDER")  && get old border setting
  2739.    if .not. type("m->cBorder") = "L"  && if user set border ...
  2740.       set border to &cBorder.         && start NEW border setting
  2741.    endif
  2742.    m->nBorder   = iif(set("BORDER") = "NONE",0,2)  && border factor
  2743.  
  2744.    *-- get window coordinates
  2745.    *-- this centers from top to bottom, depending on monitor setup ...
  2746.    m->nULRow = iif(val(right(set("DISPLAY"),2)) = 43,18,8)
  2747.  
  2748.    *-- add rows, number depends on border, so the Window is large enough 
  2749.    m->nBRRow = m->nULRow + 5 +m->nBorder
  2750.  
  2751.    *-- left column ...
  2752.    m->nULCol = 40 - (max(len(m->cTitle2),len(m->cMessage2))/2)    
  2753.                                                    && center left-right
  2754.    *-- right column ...
  2755.    m->nBRCol = m->nULCol + max(len(m->cTitle2),len(m->cMessage2)) + ;
  2756.                (m->nBorder - 1)
  2757.    *-- Window width ...
  2758.    m->nWidth = m->nBRCol - m->nULCol - 1
  2759.  
  2760.    *-- define window
  2761.    Define window wAlert from m->nULRow,m->nULCol to ;
  2762.                              m->nBRRow,m->nBRCol color &cColor.
  2763.  
  2764.    *-- display shadow
  2765.    do shadow with m->nULRow,m->nULCol,m->nBRRow,m->nBRCol
  2766.  
  2767.    *-- start 'er up ...
  2768.    activate window wAlert
  2769.  
  2770.    *-- display  a new type type line to look more like Win
  2771.    m->cTempCol = colorbrk(m->cColor,2)
  2772.    m->cColorF   = FBClrBrk("B",m->cTempCol) 
  2773.                                   && background of title bar text
  2774.    m->cColorB   = FBClrBrk("B",colorbrk(m->cColor,1)) 
  2775.                                   && foreground of 'normal' text
  2776.    m->cColorAll = m->cColorF + "/" + m->cColorB          
  2777.                                   && color of 'special' line
  2778.    @ 0,0 say justify(m->cTitle2,m->nWidth + ;
  2779.                      iif(m->nBorder = 0,4,2),"C") ;
  2780.                      color &cTempCol.          && the Title Bar
  2781.    *-- chr(223) looks like this --> ï¬‚ <--
  2782.    @ 1,0 say replicate(chr(223),m->nWidth + 2) color &cColorAll.
  2783.                                     && make thicker
  2784.  
  2785.    *-- display message
  2786.    @ 2,0 say justify(m->cMessage2,m->nWidth + ;
  2787.                      iif(m->nBorder = 0,4,2),"C")
  2788.    *-- define/display a very small menu (one pad)
  2789.    define menu mAlert
  2790.    define pad pPad1 of mAlert prompt "[OK]" at 4,;
  2791.                                ((m->nWidth-m->nBorder-2)/2)
  2792.    on selection pad pPad1 of mAlert deactivate menu
  2793.  
  2794.    *-- added by Ken to deal with <Enter>
  2795.    on key label ctrl-M keyboard "{27}"
  2796.  
  2797.    *-- start it up
  2798.    activate menu mAlert
  2799.  
  2800.    *-- deal with user 'input'
  2801.    mPad = pad()
  2802.    release window wAlert
  2803.  
  2804.    *-- restore environment, free up RAM by releasing things
  2805.    on key label ctrl-m
  2806.    restore screen from sTemp
  2807.    release screen sTemp
  2808.    release menu mAlert
  2809.    if "" # wWindow
  2810.        activate window &wWindow.
  2811.    endif
  2812.    set border to &cOldBorder.
  2813.    
  2814. RETURN .not. "" = mPad  && not empty pad?
  2815. *-- EoF: Alert3()
  2816.  
  2817. FUNCTION Alert4
  2818. *-----------------------------------------------------------------------
  2819. *-- Programmer..: Adam L. Menkes (SUPREME1)
  2820. *-- Date........: 03/15/1993
  2821. *-- Notes.......: This function based on Alert3()
  2822. *--               This routine creates a popup on the screen with a 
  2823. *--               title and one line message, forcing the user to 
  2824. *--               notice the message. The user must use the mouse on 
  2825. *--               the 'OK' pad, press <Esc> or press <Enter> to move on
  2826. *--               in the program that called this function.
  2827. *--               WARNING: If it matters to you, this dialog box is 
  2828. *--               two rows higher, and two columns wider than previous 
  2829. *--               versions.
  2830. *-- Written for.: dBASE IV, 1.5
  2831. *-- Rev. History: 06/19/1992 -- Original
  2832. *--               03/15/1993 -- Modified by Ken Mayer to give 3-D border 
  2833. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  2834. *--               JUSTIFY()            Function in PROC.PRG
  2835. *--               COLORBRK()           Function in PROC.PRG
  2836. *--               FBCLRBRK()           Function in PROC.PRG 
  2837. *--               BORD3D               Procedure in PROC.PRG
  2838. *-- Called by...: Any
  2839. *-- Usage.......: Alert4("<cTitle>","<cMessage>","<cColor>"[,<nStyle>])
  2840. *-- Example.....: lX = Alert4("Print Aborted","You pressed <ESC>",;
  2841. *--                           "rg+/r,w+/b,rg+/r",2)
  2842. *-- Returns.....: Logical
  2843. *-- Parameters..: cTitle   = Title line
  2844. *--               cMessage = One line message (up to 75 characters)
  2845. *--               cColor   = Colors: <window forg/back>,<pad> (and 
  2846. *--                          title),<box>
  2847. *--               nStyle   = OPTIONAL: Style 1 (default) = raised border
  2848. *--                                    Style 2           = inset border
  2849. *-----------------------------------------------------------------------
  2850.  
  2851.    parameters cTitle, cMessage, cColor, nStyle
  2852.    private wWindow,mPad,cTempCol,cColorF,cColorB,cColorAll
  2853.    private nWidth,nULRow,nULCol,nLRRow,nLRCol,cTitle2,cMessage2
  2854.  
  2855.    m->cTitle2 = " " + ltrim(trim(m->cTitle)) + " "      
  2856.                                       && don't jamb against walls
  2857.    m->cMessage2 = " " + ltrim(trim(m->cMessage)) + " "  
  2858.                                       && don't jamb against walls
  2859.    wWindow = WINDOW()                 && save current Window
  2860.    save screen to sTemp               && save the screen
  2861.    activate screen
  2862.    m->cDummykey = inkey()             && clear out keyboard buffer
  2863.    if pCount() < 4
  2864.       m->nStyle = 1
  2865.    endif
  2866.    
  2867.    *-- get window coordinates
  2868.    *-- this centers from top to bottom, depending on monitor setup ...
  2869.    m->nULRow = iif(val(right(set("DISPLAY"),2)) = 43,18,8)
  2870.    *-- add rows, number depends on border, so the Window is large enough
  2871.    m->nBRRow = m->nULRow + 8
  2872.  
  2873.    *-- left column ...
  2874.    m->nULCol = (40 - (max(len(m->cTitle2),len(m->cMessage2))/2)) -2 
  2875.                                         && center left-right
  2876.    *-- right column ...
  2877.    m->nBRCol = m->nULCol + max(len(m->cTitle2),len(m->cMessage2)) + 5
  2878.    *-- Window width ...
  2879.    m->nWidth = m->nBRCol - m->nULCol
  2880.  
  2881.    *-- define window (with no border so we can place the 3-D one on it)
  2882.    Define window wAlert from m->nULRow,m->nULCol to m->nBRRow,m->nBRCol;
  2883.                                                    NONE color &cColor.
  2884.  
  2885.    *-- display shadow
  2886.    do shadow with m->nULRow,m->nULCol,m->nBRRow,m->nBRCol
  2887.  
  2888.    *-- start 'er up ...
  2889.    activate window wAlert
  2890.  
  2891.    *-- put 3-D Border in there
  2892.    do BORD3D with (m->nBRRow-m->nULRow),m->nWidth,m->cColor, m->nStyle
  2893.  
  2894.    *-- display  a new type type line to look more like Win
  2895.    m->cTempCol = colorbrk(m->cColor,2)
  2896.    m->cColorF   = FBClrBrk("B",m->cTempCol)      
  2897.                                && background of title bar text
  2898.    m->cColorB   = FBClrBrk("B",colorbrk(m->cColor,1)) 
  2899.                                && foreground of 'normal' text
  2900.    m->cColorAll = m->cColorF + "/" + m->cColorB          
  2901.                                && color of 'special' line
  2902.    @ 2,3 say justify(m->cTitle2,m->nWidth - 5 ,"C");
  2903.                color &cTempCol.            && the Title Bar
  2904.    *-- chr(223) looks like this --> ï¬‚ <--
  2905.    @ 3,3 say replicate(chr(223),m->nWidth - 5) color &cColorAll.
  2906.                                && make thicker
  2907.  
  2908.    *-- display message
  2909.    @ 4,3 say justify(m->cMessage2,m->nWidth - 5,"C")
  2910.    *-- define/display a very small menu (one pad)
  2911.    define menu mAlert
  2912.    define pad pPad1 of mAlert prompt "[OK]" at 6,((m->nWidth-5)/2)+1
  2913.    on selection pad pPad1 of mAlert deactivate menu
  2914.  
  2915.    *-- added by Ken to deal with <Enter>
  2916.    on key label ctrl-M keyboard "{27}"
  2917.  
  2918.    *-- start it up
  2919.    activate menu mAlert
  2920.  
  2921.    *-- deal with user 'input'
  2922.    mPad = pad()
  2923.    deactivate window wAlert
  2924.    release window wAlert
  2925.  
  2926.    *-- restore environment, free up RAM by releasing things
  2927.    on key label ctrl-m
  2928.    restore screen from sTemp
  2929.    release screen sTemp
  2930.    release menu mAlert
  2931.    if "" # wWindow
  2932.        activate window &wWindow.
  2933.    endif
  2934.    
  2935. RETURN .not. "" = mPad  && not empty pad?
  2936. *-- EoF: Alert4()
  2937.  
  2938. FUNCTION Alert5
  2939. *-----------------------------------------------------------------------
  2940. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  2941. *-- Date........: 06/11/1993
  2942. *-- Notes.......: This is a general purpose "ALERT" dialog box. It is
  2943. *--               based heavily on the original work by Adam L. Menkes
  2944. *--               (Borland Technical Support), and Joey D. Carrol, as 
  2945. *--               well as various tinkerings I have done in previous 
  2946. *--               versions. This routine creates a popup on the screen 
  2947. *--               with a title and one line message, forcing the user 
  2948. *--               to notice the message.
  2949. *--               The user must use the mouse on the 'OK' pad, press 
  2950. *--               <Esc> or press <Enter> to move on in the program 
  2951. *--               that called this function.
  2952. *-- Written for.: dBASE IV, 1.5
  2953. *-- Rev. History: 06/19/1992 -- Adam L. Menkes -- Original "Alert()" 
  2954. *--                             routine.
  2955. *--               06/11/1993 -- Kenneth J. Mayer -- complete overhaul.
  2956. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  2957. *--               JUSTIFY()            Function in PROC.PRG
  2958. *--               COLORBRK()           Function in PROC.PRG
  2959. *--               FBCLRBRK()           Function in PROC.PRG 
  2960. *--               BORD3D5              Procedure in DIALOGS.PRG
  2961. *-- Called by...: Any
  2962. *-- Usage.......: Alert5("<cTitle>","<cMessage>","<cColor>"[,<nStyle>])
  2963. *-- Example.....: lX = Alert5("Print Aborted","You pressed <ESC>",;
  2964. *--                           "rg+/r,w+/b,rg+/r",2)
  2965. *-- Returns.....: Logical
  2966. *-- Parameters..: cTitle   = Title line
  2967. *--               cMessage = One line message (up to 254 characters)
  2968. *--               cColor   = Colors: <window forg/back>,<pad> (and 
  2969. *--                          title),<box>
  2970. *--                          Default is to "steel" grey
  2971. *--               nStyle   = OPTIONAL: 1 = double raised border(default)
  2972. *--                                    2 = double recessed bord
  2973. *--                                    3 = single raised
  2974. *--                                    4 = single recessed
  2975. *-----------------------------------------------------------------------
  2976.  
  2977.    parameters cTitle, cMessage, cColor, nStyle
  2978.    private wWindow,mPad,cTempCol,cColorF,cColorB,cColorAll
  2979.    private nWidth,nTop,nLeft,nBottom,nRight,cTitle2,cMessage2
  2980.  
  2981.    m->cTitle2 = " " + ltrim(trim(m->cTitle)) + " "      
  2982.                                        && don't jamb against walls
  2983.    m->cMessage2 = " " + ltrim(trim(m->cMessage)) + " "  
  2984.                                        && don't jamb against walls
  2985.    wWindow = WINDOW()                  && save current Window
  2986.    save screen to sTemp                && save the screen
  2987.    activate screen
  2988.    m->cDummykey = inkey()              && clear out keyboard buffer
  2989.  
  2990.    *-- deal with defaults
  2991.    if pCount() < 4 .or. (m->nStyle < 1 .or. m->nStyle > 4)
  2992.       m->nStyle = 1
  2993.    endif
  2994.    if pCount() < 3                     && no colors? default to grey
  2995.       m->cColor = "n/w,w+/n,n/w"
  2996.    endif
  2997.    if isblank(m->cColor) 
  2998.       m->cColor = "n/w,w+/n,n/w"
  2999.    endif
  3000.    
  3001.    *-- determine coordinates -- we're basing some of this on YESNO()
  3002.    *-- routines -- alert box will be only so wide ...
  3003.    m->nWidth = 36 + iif(m->nStyle<3,4,2) 
  3004.    
  3005.    *-- height will be based on how many lines of message we have
  3006.    m->nHeight = int(len(m->cMessage)/m->nWidth) +;
  3007.              iif(mod(len(m->cMessage),m->nWidth) > 0,1,0) +;
  3008.              iif(m->nStyle < 3,3,1) + 6
  3009.    
  3010.    *-- now we have height and width, let's determine where 
  3011.    *-- to center this. First, we need screen height
  3012.    m->cScreen = set("DISPLAY")
  3013.    if m->cScreen = "MONO"
  3014.       m->nScreen = 24
  3015.    else
  3016.       m->nScreen = val(right(m->cScreen,2)) - 1  && (EGA25 = 0 to 24)
  3017.    endif
  3018.    
  3019.    *-- now to determine coordinates
  3020.    m->nTop     = (m->nScreen - m->nHeight) / 2
  3021.    m->nBottom  = m->nTop + m->nHeight
  3022.    m->nLeft    = 20
  3023.    m->nRight   = m->nLeft + m->nWidth
  3024.    
  3025.    *-- define window (with no border so we can place the 3-D one on it)
  3026.    Define window wAlert from m->nTop,m->nLeft to m->nBottom,m->nRight ;
  3027.                                                  NONE color &cColor.
  3028.  
  3029.    *-- display shadow
  3030.    do shadow with m->nTop,m->nLeft,m->nBottom,m->nRight
  3031.  
  3032.    *-- start 'er up ...
  3033.    activate window wAlert
  3034.  
  3035.    *-- put 3-D Border in there
  3036.    m->cBordCol = colorbrk(m->cColor,1)
  3037.    do BORD3D5 with 0,0,(m->nBottom-m->nTop),m->nWidth,m->cBordCol,;
  3038.                                                       m->nStyle
  3039.  
  3040.    *-- display a new type title line to look more like Win
  3041.    if len(m->cTitle) < m->nWidth
  3042.       m->cTitle = justify(m->cTitle,35,"C")
  3043.       if len(m->cTitle) < 35
  3044.          m->cTitle = m->cTitle + " "
  3045.       endif
  3046.    endif
  3047.    m->cTempCol = colorbrk(m->cColor,2)
  3048.    m->cColorF   = FBClrBrk("B",cTempCol)           
  3049.                                        && background of title bar text
  3050.    m->cColorB   = FBClrBrk("B",colorbrk(m->cColor,1)) 
  3051.                                        && foreground of 'normal' text
  3052.    m->cColorAll = m->cColorF + "/" + m->cColorB          
  3053.                                        && color of 'special' line
  3054.    m->nRow = iif(m->nStyle<3,2,1)
  3055.    m->nCol = iif(m->nStyle<3,3,2)
  3056.    @m->nRow,  m->nCol say m->cTitle color &cTempCol.     
  3057.                                        && the Title Bar
  3058.    @m->nRow+1,m->nCol say replicate(chr(223),35) color &cColorAll.  
  3059.  
  3060.    *-- display message
  3061.    do WordWrap with iif(m->nStyle<3,4,3),iif(m->nStyle<3,4,3),;
  3062.                                          m->cMessage,34
  3063.  
  3064.    *-- define/display a very small menu (one pad)
  3065.    define menu mAlert
  3066.    m->nButtonRow = m->nHeight - iif(m->nStyle<3,3,2)
  3067.    m->nButtonCol = m->nWidth/2 - 1
  3068.    define pad pPad1 of mAlert prompt "[OK]" at m->nButtonRow,;
  3069.                                                m->nButtonCol
  3070.    on selection pad pPad1 of mAlert deactivate menu
  3071.  
  3072.    *-- added by Ken to deal with <Enter>
  3073.    on key label ctrl-M keyboard "{27}"
  3074.  
  3075.    *-- before starting, put a border around the button
  3076.    do bord3d5 with m->nButtonRow-1,m->nButtonCol-1,m->nButtonRow+1,;
  3077.                                    m->nButtonCol+4,m->cBordCol,3
  3078.  
  3079.    *-- start it up
  3080.    activate menu mAlert
  3081.  
  3082.    *-- deal with user 'input'
  3083.    mPad = pad()
  3084.    deactivate window wAlert
  3085.    release window wAlert
  3086.  
  3087.    *-- restore environment, free up RAM by releasing things
  3088.    on key label ctrl-m
  3089.    restore screen from sTemp
  3090.    release screen sTemp
  3091.    release menu mAlert
  3092.    if "" # wWindow
  3093.        activate window &wWindow.
  3094.    endif
  3095.    
  3096. RETURN .not. "" = mPad  && not empty pad?
  3097. *-- EoF: Alert5()
  3098.  
  3099. FUNCTION Surround2
  3100. *-----------------------------------------------------------------------
  3101. *-- Programmer..: Miriam Liskin
  3102. *-- Date........: 03/18/1993
  3103. *-- Notes.......: Displays a message surrounded by a box anywhere on 
  3104. *--               the screen -- this version centers automatically on
  3105. *--               the screen and gives a 3-D border ...
  3106. *-- Written for.: dBASE IV, 1.5
  3107. *-- Rev. History: 04/19/1991 - Modified by Ken Mayer (CIS: 71333,1030) 
  3108. *--                            to a function from original procedure
  3109. *--               05/24/1991 -- Added shadow
  3110. *--               03/18/1993 -- Made 3D, and auto-center at "row".
  3111. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  3112. *--               BORD3D2              Procedure in PROC.PRG
  3113. *-- Called by...: Any
  3114. *-- Usage.......: surround2(<nLine>,"<cColor>","<cText>"[,<nStyle>])
  3115. *-- Example.....: cDummy = surround2(5,12,"RG+/GB",;
  3116. *--                        "Processing ... Do not Touch!",1)
  3117. *-- Returns.....: Nul/""
  3118. *-- Parameters..: nLine   = Line to display "surrounded" message at
  3119. *--               cColor  = Color variable/colors
  3120. *--               cText   = Text to be displayed inside box
  3121. *--               nStyle  = Style of border (1 = Raised, 2 = Recessed)
  3122. *--                         OPTIONAL
  3123. *-----------------------------------------------------------------------
  3124.    
  3125.    parameters nLine,cColor,cText,nStyle
  3126.    
  3127.    if pCount() < 4
  3128.       m->nStyle = 1
  3129.    endif
  3130.    
  3131.    *-- deal with border -- save old setting, set to single
  3132.    m->cBorder = set("BORDER")
  3133.    set border to single
  3134.    
  3135.    m->cText2 = " "+trim(m->cText)+" "             
  3136.                                        && add spaces to left and right
  3137.    m->nTextStart = (81-len(trim(m->cText2)))/2    
  3138.                                        && centered text on screen
  3139.    activate screen
  3140.    m->nTop    = m->nLine - 2
  3141.    m->nLeft   = m->nTextStart - 3       && back up 3
  3142.    m->nBottom = m->nLine + 2            && bottom row
  3143.    m->nRight  = (81-m->nTextStart) + 3  && right 3
  3144.    
  3145.    *-- draw shadow
  3146.    do shadow with m->nTop,m->nLeft,m->nBottom,m->nRight
  3147.    
  3148.    *-- fill in box
  3149.    @m->nTop,m->nLeft fill to m->nBottom,m->nRight color &cColor.
  3150.    
  3151.    *-- place border on top of it
  3152.    do bord3d2 with m->nTop,m->nLeft,m->nBottom,m->nRight,;
  3153.                    m->cColor,m->nStyle
  3154.    
  3155.    *-- finally, let's display the text ...
  3156.    @m->nLine, m->nTextStart say m->cText2 color &cColor. && display text
  3157.    
  3158. RETURN "" 
  3159. *-- EoF: Surround2()
  3160.  
  3161. FUNCTION Surround3
  3162. *-----------------------------------------------------------------------
  3163. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  3164. *-- Date........: 06/09/1993
  3165. *-- Notes.......: Displays a message surrounded by a box anywhere on 
  3166. *--               the screen -- this version centers automatically on
  3167. *--               the screen and gives a 3-D border ...
  3168. *--               This is based on the original routine by Miriam 
  3169. *--               Liskin.
  3170. *-- Written for.: dBASE IV, 1.5
  3171. *-- Rev. History: 06/09/1993 -- Original
  3172. *-- Calls.......: SHADOW               Procedure in PROC.PRG
  3173. *--               BORD3D5              Procedure in DIALOGS.PRG
  3174. *-- Called by...: Any
  3175. *-- Usage.......: surround3(<nLine>,"<cColor>","<cText>"[,<nStyle>])
  3176. *-- Example.....: cDummy = surround3(5,12,"RG+/GB",;
  3177. *--                        "Processing ... Do not Touch!",1)
  3178. *-- Returns.....: Nul/""
  3179. *-- Parameters..: nLine   = Line to display "surrounded" message at
  3180. *--                         if nLine = 0, we will center on the screen
  3181. *--                         vertically, as well as horizontally.
  3182. *--               cColor  = Color variable/colors (Default to grey)
  3183. *--               cText   = Text to be displayed inside box
  3184. *--               nStyle  = Style of border 1 = Double - Raised(Default)
  3185. *--                                         2 = Double - Recessed
  3186. *--                                         3 = Single - Raised
  3187. *--                                         4 = Double - Recessed
  3188. *--                          NOTE: This is OPTIONAL
  3189. *-----------------------------------------------------------------------
  3190.    
  3191.    parameters nLine,cColor,cText,nStyle
  3192.    private nStyle, cColor, cBorder, cText2, nTextStart, nTop, nLeft, ;
  3193.            nBottom, nRight, nLine
  3194.    
  3195.    *-- deal with defaults
  3196.    if pCount() < 4 .or. (m->nStyle < 1 .or. m->nStyle > 4) 
  3197.                                        && set default border style
  3198.       m->nStyle = 1
  3199.    endif
  3200.    if isblank(m->cColor)
  3201.       m->cColor = "n/w"
  3202.    endif
  3203.    
  3204.    *-- deal with nLine being equal to 0 when user passes this 
  3205.    *-- (this will cause the routine to center on the screen ... 
  3206.    *-- no matter how the screen is set).
  3207.    if m->nLine = 0
  3208.       m->cScreen = set("DISPLAY")
  3209.       if m->cScreen = "MONO"
  3210.          m->nScreen = 24
  3211.       else
  3212.          m->nScreen = val(right(m->cScreen,2)) - 1  && EGA25 = 0 to 24
  3213.       endif
  3214.       m->nLine = int(m->nScreen/2)  && halfway ...
  3215.    endif
  3216.    
  3217.    m->cText2 = " "+trim(m->cText)+" "  && add spaces to left and right
  3218.    m->nTextStart = (81-len(trim(m->cText2)))/2    
  3219.                                        && centered text on screen
  3220.    activate screen
  3221.    m->nTop    = m->nLine - iif(m->nStyle < 3,2,1)  && up 2 or 1 ...
  3222.    m->nLeft   = m->nTextStart - iif(m->nStyle < 3,3,2) 
  3223.                                        && back up 3 (or 2 if single)
  3224.    m->nBottom = m->nLine + iif(m->nStyle < 3,2,1)  && bottom row
  3225.    m->nRight  = (81-m->nTextStart) + iif(m->nStyle < 3,3,2) 
  3226.                                        && right 3 (or 2 if single)
  3227.    
  3228.    *-- draw shadow
  3229.    do shadow with m->nTop,m->nLeft,m->nBottom,m->nRight
  3230.    
  3231.    *-- fill in box
  3232.    @m->nTop,m->nLeft fill to m->nBottom,m->nRight color &cColor.
  3233.    
  3234.    *-- place border on top of it
  3235.    do bord3d5 with m->nTop,m->nLeft,m->nBottom,m->nRight,;
  3236.                    m->cColor,m->nStyle
  3237.    
  3238.    *-- finally, let's display the text ...
  3239.    @m->nLine, m->nTextStart say m->cText2 color &cColor. && display text
  3240.    
  3241. RETURN "" 
  3242. *-- EoF: Surround3()
  3243.  
  3244. FUNCTION Radio
  3245. *-----------------------------------------------------------------------
  3246. *-- Programmer..: Ed Lafferty (CIS: 76150,3302)
  3247. *-- Date........: 06/08/1992
  3248. *-- Notes.......: Routine to create and size a popup with radio buttons
  3249. *--               for choosing only one of up to four options.  Pressing
  3250. *--               the <Space Bar> on an option turns it on or off.
  3251. *--               Pressing <Enter> chooses the selected option and 
  3252. *--               leaves the routine.
  3253. *-- Written for.: dBase IV, 1.1
  3254. *-- Rev. History: 02/25/1992 - original procedure.
  3255. *--               02/27/1992 -- Ken Mayer -- added option for color, 
  3256. *--               but had to take number of choices back to 4 to do so. 
  3257. *--               Minor alterations performed to add color choice ... 
  3258. *--               and cleaning up after self ... (original cleared the 
  3259. *--               screen first ... this version saves screen, restores 
  3260. *--               back to it ...) Oh yeah, I turned it into a function, 
  3261. *--               rather than a procedure, as well.
  3262. *-- Calls.......: CENTER                Procedure in PROC.PRG
  3263. *--               SHADOW                Procedure in PROC.PRG
  3264. *--               COLORBRK()            Function in PROC.PRG
  3265. *-- Called by...: Any
  3266. *-- Usage.......: Radio(<nULRow>,<nULCol>,<nChoice>,"<cTxt1>",;
  3267. *--                     "<cTxt2>","<cTxt3>","<cTxt4>","<cTitle>",;
  3268. *--                     "<cColor>")
  3269. *-- Example.....: cPort = Radio(8,15,1,"LPT1","LPT2","LPT3","",;
  3270. *--                       "Choose a printer port","rg+/gb,n/w,rg+/gb")
  3271. *-- Returns.....: number of chosen button in nChoice
  3272. *-- Parameters..: nUlrow  = upper left row of popup
  3273. *--               nUlcol  = upper left column of popup
  3274. *--               nChoice = default chosen button
  3275. *--               cTxt1   = Text for 1st button
  3276. *--               cTxt2   =  "    "  2nd   "
  3277. *--               cTxt3   =  "    "  3rd   "
  3278. *--               cTxt4   =  "    "  4th   "
  3279. *--               cTitle  = Text for the box title
  3280. *--               cColor  = Color string (i.e., "RG+/GB,N/W,RG+/GB") 
  3281. *-----------------------------------------------------------------------
  3282.  
  3283.  
  3284.    parameters nUlrow, nUlcol, nChoice, cTxt1, cTxt2, cTxt3, cTxt4, ;
  3285.                cTitle, cColor
  3286.    private nHeight, nKey, nCnt, nWidth, cStr, cTxt0, cMidCol, ;
  3287.            cFirstCol, cCursor
  3288.    
  3289.    m->cCursor = set("CURSOR")
  3290.    store m->cTitle to m->cTxt0
  3291.    save screen to sRadio
  3292.    store 0 to m->nHeight, m->nKey, m->nCnt, m->nWidth
  3293.    store m->nChoice to m->nOrig  && in case user presses <Esc> to exit 
  3294.    
  3295.    *-- deal with these colors in displaying some stuff ...
  3296.    m->cMidCol = colorbrk(m->cColor,2)
  3297.    *-- First color (for message) is easier ...
  3298.    m->cFirstCol = colorbrk(m->cColor,1)
  3299.    
  3300.    *-- Determine height and width of popup
  3301.    do case
  3302.       case len(m->cTxt4) > 0
  3303.          m->nHeight = 4
  3304.       case len(m->cTxt3) > 0
  3305.          m->nHeight = 3
  3306.       case len(m->cTxt2) > 0
  3307.          m->nHeight = 2
  3308.       otherwise
  3309.          m->nHeight = 1
  3310.    endcase
  3311.    
  3312.    do while m->nCnt <= m->nHeight
  3313.       store "cTxt"+str(m->nCnt,1) to m->cStr
  3314.       if len(&cstr.) > m->nWidth
  3315.          m->nWidth = len(&cStr.)
  3316.       endif
  3317.       m->nCnt = m->nCnt + 1
  3318.    enddo
  3319.    
  3320.    *-- create popup
  3321.    define window wRadio from m->nULRow,m->nULCol to ;
  3322.                         m->nULRow+m->nHeight+3,m->nULCol+m->nWidth+9;
  3323.                         double color &cColor.
  3324.    do center with 23,80,m->cFirstCol,"Press "+chr(24)+chr(25)+;
  3325.                       ", <Space> to select/de-select, <Enter> to quit"
  3326.    activate screen
  3327.    do shadow with m->nULRow, m->nULCol, m->nULRow+m->nHeight+3, ;
  3328.                                         m->nULCol+m->nWidth+9
  3329.    activate window wRadio
  3330.    
  3331.    *-- display screen
  3332.    store 1 to m->nCnt
  3333.    do center with 0, m->nWidth+8, "", m->cTitle
  3334.    do while m->nCnt <= m->nHeight
  3335.       store "cTxt"+str(m->nCnt,1) to m->cStr
  3336.       @ m->nCnt+1, 2 SAY "[ ]" color &cMidCol.
  3337.       @ m->nCnt+1, 6 say &cStr.
  3338.       m->nCnt = m->nCnt + 1
  3339.    enddo
  3340.    
  3341.    *-- prepare for and get nChoice
  3342.    if m->nChoice > 0
  3343.       store m->nChoice to m->nCnt
  3344.       @m->nCnt+1,3 say "Ë›" color &cMidCol.
  3345.    else
  3346.       store 1 to m->nCnt
  3347.    endif
  3348.    store .F. to m->lDone
  3349.    
  3350.    *-- this loop processes user input ... 
  3351.    do while .not. m->lDone
  3352.       @ m->nCnt+1,3 say "" color &cMidCol.
  3353.       m->nKey = inkey(0)
  3354.       do case
  3355.       case m->nKey = 27                   && Press Esc to exit
  3356.          store m->nOrig to m->nChoice     && Leave at "default"
  3357.          store .T. to m->lDone
  3358.       case m->nKey = 13
  3359.          store .T. to m->lDone
  3360.       case m->nKey = 32                   && Press Enter or Space
  3361.             set cursor off
  3362.             if m->nChoice = m->nCnt
  3363.                @ m->nCnt+1,3 say " " color &cMidCol.
  3364.                store 0 to m->nChoice
  3365.             else
  3366.                @ m->nChoice+1,3 say " " color &cMidCol.
  3367.                @ m->nCnt+1,3 say "Ë›" color &cMidCol.
  3368.                store m->nCnt to m->nChoice
  3369.             endif
  3370.             set cursor on
  3371.       case m->nKey = 5                    && Press up arrow
  3372.          if m->nCnt > 1
  3373.             m->nCnt = m->nCnt - 1
  3374.          else
  3375.             m->nCnt = m->nHeight
  3376.          endif
  3377.       case m->nKey = 24                   && Press down arrow
  3378.          if m->nCnt < m->nHeight
  3379.             m->nCnt = m->nCnt + 1
  3380.          else
  3381.             m->nCnt = 1
  3382.          endif
  3383.       endcase
  3384.    enddo
  3385.    
  3386.    *-- cleanup
  3387.    release window wRadio
  3388.    restore screen from sRadio
  3389.    release screen sRadio
  3390.    set message to
  3391.    set cursor &cCursor.
  3392.    
  3393. RETURN m->nChoice
  3394. *-- EoF: Radio()
  3395.  
  3396. PROCEDURE CheckBox
  3397. *-----------------------------------------------------------------------
  3398. *-- Programmer..: Ed Lafferty (CIS: 76150,3302)
  3399. *-- Date........: 04/22/1993
  3400. *-- Notes.......: Routine to create and size a popup with check boxes
  3401. *--               for choosing any of a number (up to five) options.  
  3402. *--               Pressing the <Space Bar> on an option turns it on or 
  3403. *--               off. Pressing <Enter> chooses the selected option and
  3404. *--               leaves the routine. You must use a data structure with
  3405. *--               logical fields, or memvars that are logical for this. 
  3406. *--               Either way, even if you don't use five logical 
  3407. *--               fields/memvars, you must pass a field/memvar to the 
  3408. *--               procedure -- see Example below (the logicals -- lCHK1,
  3409. *--               lCHK2, etc.-- must be fields or memvars due to a 
  3410. *--               limitation in parameter passing in dBASE IV.)
  3411. *-- Written for.: dBase IV, Version 1.5+
  3412. *-- Rev. History: 02/25/1992 -- Original procedure.
  3413. *--               02/28/1992 -- Ken Mayer -- modified to allow passing 
  3414. *--                             cColor, and a little cleanup of code 
  3415. *--                             and such. Minor changes.
  3416. *--               04/22/1993 -- Angus Scott-Fleming:
  3417. *--                   Revised for 1.5:
  3418. *--                   Turned cursor on
  3419. *--                   Moved help-line info inside box.
  3420. *--                   Reorganized parameters to allow calling
  3421. *--                      with variable # of choices, and evaluate with 
  3422. *--                      pCOUNT()
  3423. *--                   NOTE: If more than 9 pairs are needed, two loops 
  3424. *--                      will have to be changed from STR(NCNT,1) to 
  3425. *--                      lTrim(STR(cCnt,2))
  3426. *--                   Enabled error-trapping for poorly located boxes.
  3427. *--                   Appended "." to all &Macros.
  3428. *-- Calls.......: CENTER               Procedure in PROC.PRG
  3429. *--               SHADOW               Procedure in PROC.PRG
  3430. *--               COLORBRK()           Function in PROC.PRG
  3431. *-- Called by...: Any
  3432. *-- Usage.......: do checkbox with <nULCol>,<nULRow>,<cTitle>,<cColor>,;
  3433. *--                          <lchk1>,<cTxt1>,[<lchk2>,<cTxt2>];
  3434. *--                          [,<lchk3>,<cTxt3>][,<lchk4>,<cTxt4>];
  3435. *--                          [... to 9]
  3436. *-- Example.....: do Checkbox with 8, 15, "Choose a printer port",;
  3437. *--                    "rg+/gb,w+/n,rg+/gb", lchk1, "LPT1", lchk2, ;
  3438. *--                     "LPT2", lchk3, "LPT3"
  3439. *-- Returns.....: .T. for selected items, .F. for non-selected items --
  3440. *--               this routine changes the value of the logical fields 
  3441. *--               passed to it.
  3442. *-- Parameters..: nULRow = upper left row of popup
  3443. *--               nULCol = upper left column of popup
  3444. *--               cTitle = Title for box
  3445. *--               cColor = Colors for window
  3446. *--               lChkn  = default value of box 'n' -- 
  3447. *--                        MUST BE FIELDS/MEMVARS
  3448. *--               cTxtn  = Text for 'n'th box
  3449. *--               cColor = Colors to be used in window ...
  3450. *-----------------------------------------------------------------------
  3451.  
  3452.    parameters nUlrow, nUlcol, cTitle, cColor, lChk1, cTxt1, lChk2, ;
  3453.               cTxt2,lChk3, cTxt3, lChk4, cTxt4, lChk5, cTxt5, lChk6,;
  3454.               cTxt6,lChk7, cTxt7, lChk8, cTxt8, lChk9, cTxt9
  3455.    private nHeight, nKey, nCnt, nWidth, cMidCol, cFirstCol, cCursor,;
  3456.               cPrompt, nBRRow, nBRCol
  3457.    
  3458.    *-- setup ...
  3459.    m->cCursor = set("CURSOR")
  3460.    save screen to sCheck
  3461.    store 0 to m->nHeight, m->nKey, m->nWidth
  3462.    m->cPrompt = "Press "+chr(24)+chr(25)+;
  3463.       ", <Space> to select/de-select, <Enter> to quit"
  3464.       
  3465.    *-- save original settings, in case <Esc> gets pressed below ...
  3466.    *-- determine height/width of popup
  3467.    m->nWidth  = max(len(m->cPrompt),len(m->cTitle))
  3468.    m->nHeight = (pcount() - 4)/2
  3469.    m->nCnt    = 0
  3470.    do while m->nCnt < m->nHeight
  3471.       m->nCnt = m->nCnt + 1
  3472.       m->cCnt = str(m->nCnt,1)
  3473.       private lOrig&cCnt.
  3474.       store lChk&cCnt. to lOrig&cCnt.
  3475.       m->nWidth = max(m->nWidth,len(cTxt&cCnt.))
  3476.    enddo
  3477.    *-- add border to window
  3478.    m->nWidth = min(m->nWidth+8,79)
  3479.    
  3480.    *-- deal with some colors ...
  3481.    m->cMidCol   = colorbrk(m->cColor,2)
  3482.    m->cFirstCol = colorbrk(m->cColor,1)
  3483.    
  3484.    *-- create popup and trap errors defining the window
  3485.    m->nBRRow = m->nULRow + m->nHeight + 5
  3486.    m->nBRCol = m->nULCol + m->nWidth
  3487.    if m->nBRRow > 24
  3488.       *-- center window vertically
  3489.       m->nULRow = max(12-(m->nHeight+5)/2,0)
  3490.       m->nBRRow = min(23,(m->nULRow+m->nHeight+5))
  3491.    endif
  3492.    if m->nBRCol > 80
  3493.       *-- center window horizontally
  3494.       m->nULCol = max(40 - m->nWidth/2,0)
  3495.       m->nBRCol = min(79,(m->nULCol+m->nWidth))
  3496.    endif
  3497.    
  3498.    define window wCheck from m->nULRow, m->nULCol to m->nBRRow,;
  3499.                                         m->nBRCol double color &cColor.
  3500.    activate screen
  3501.    do shadow with m->nULRow,m->nULCol,m->nBRRow,m->nBRCol
  3502.    activate window wCheck
  3503.    
  3504.    *-- paint screen
  3505.    do center with 0,m->nWidth,"",m->cTitle
  3506.    store 1 to m->nCnt
  3507.    do while m->nCnt <= m->nHeight
  3508.       store "cTxt"+str(m->nCnt,1) to m->cStr
  3509.       store "lChk"+str(m->nCnt,1) to cChk
  3510.       @m->nCnt+1,2 say "["+iif(&cChk.,"X"," ")+"]" color &cMidCol.
  3511.       @m->nCnt+1,6 say left(&cStr.,m->nWidth-9)
  3512.       m->nCnt = m->nCnt + 1
  3513.    enddo
  3514.    do center with m->nCnt+2,m->nWidth,"",m->cPrompt
  3515.       
  3516.    *-- prepare for and get nChoice
  3517.    store 1 to m->nCnt
  3518.    store .F. to m->lDone
  3519.    do while .not. m->lDone
  3520.       store "lChk"+str(m->nCnt,1) to m->cChk
  3521.       @ m->nCnt+1,3 say "" color &cMidCol.
  3522.       m->nKey = inkey(0)
  3523.       do case
  3524.          case m->nKey = 27                   && Press Esc to exit
  3525.             m->nCnt = 0
  3526.             do while m->nCnt < m->nHeight
  3527.                m->nCnt = m->nCnt + 1
  3528.                m->cCnt = str(m->nCnt,1)
  3529.                store lOrig&cCnt. to lChk&cCnt.
  3530.             enddo
  3531.             store .T. to m->lDone
  3532.          case m->nKey = 13                && Press Enter when finished
  3533.             store .T. to m->lDone
  3534.          case m->nKey = 32                && Press Space
  3535.                set cursor off
  3536.                if &cChk.                  && Box was already selected,
  3537.                   @ m->nCnt+1,3 say " " color &cMidCol.  
  3538.                                           && so now de-select it
  3539.                   store .F. to &cChk.
  3540.                else                     && Box was not already selected,
  3541.                   @ m->nCnt+1,3 say "X" color &cMidCol.  
  3542.                                         && so now select it
  3543.                   store .T. to &cChk.
  3544.                endif
  3545.                set cursor on
  3546.          case m->nKey = 5               && Press up arrow
  3547.             if m->nCnt > 1
  3548.                m->nCnt = m->nCnt - 1
  3549.             else
  3550.                m->nCnt = m->nHeight
  3551.             endif
  3552.          case m->nKey = 24              && Press down arrow
  3553.             if m->nCnt < m->nHeight
  3554.                m->nCnt = m->nCnt + 1
  3555.             else
  3556.                m->nCnt = 1
  3557.             endif
  3558.       endcase
  3559.    enddo
  3560.    
  3561.    *-- Cleanup
  3562.    release window wCheck
  3563.    restore screen from sCheck
  3564.    release screen sCheck
  3565.    set message to
  3566.    set cursor &cCursor.
  3567.    
  3568. RETURN
  3569. *-- EoP: ChkBox
  3570.  
  3571. PROCEDURE MultiPick
  3572. *-----------------------------------------------------------------------
  3573. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  3574. *-- Date........: 02/06/1993
  3575. *-- Notes.......: Permits selecting 0 or more elements of an array.
  3576. *--               The array must contain two columns, the first of which
  3577. *--               contains the prompt for the row and the second of 
  3578. *--               which contains logical .T. if the row is selected by 
  3579. *--               default, or .F.  Array may contain additional columns.
  3580. *--                     This is written for programmers, not end users.
  3581. *--               It assumes the active window and border style are set 
  3582. *--               before it is called, and no error handling is provided 
  3583. *--               for attempts to write outside the current window, 
  3584. *--               impossible colors, truncation of prompts or other 
  3585. *--               calling errors that should become evident on testing.
  3586. *--
  3587. *--               If array contains elements "Hydrangea",.T. and 
  3588. *--               "Tulip",.F., initial display after setting a window 
  3589. *--               and calling will be something like this:
  3590. *--
  3591. *--                  [ Ëš ] Hydrangea
  3592. *--                  [   ] Tulip
  3593. *--
  3594. *--               This program will use the mouse if two conditions 
  3595. *--               exist:
  3596. *--                 1) The variable nG_MusClic must exist and must hold 
  3597. *--                    the inkey() value of the character "keyboarded" 
  3598. *--                    for a click by the mouse-event handler.  Note 
  3599. *--                    that this is often, but need not be, the same as 
  3600. *--                    asc( <character> ).
  3601. *--                 2) The mouse must be made active and visible by a
  3602. *--                    mouse-control .bin such as JPMOUSE.BIN and 
  3603. *--                    MUSCLICK.BIN must be loaded and installed.
  3604. *--               *******************************
  3605. *--               **** REQUIRES MUSCLICK.BIN ****
  3606. *--               ****          JPMOUSE.BIN  ****
  3607. *--               ****          VDCURSOR.BIN ****
  3608. *--               *******************************
  3609. *-- Written for.: dBASE IV, 1.5
  3610. *-- Rev. History: 01/16/93 - original procedure
  3611. *--               02/06/93 - revised to use cWnSize, etc.
  3612. *--               02/24/93 - parameters changed, functions called moved 
  3613. *--                          out
  3614. *--               02/28/93 - symbolic constants and support for tab 
  3615. *--                          added
  3616. *-- Calls.......: SMultPick         Child procedure to paint screen
  3617. *--               Arrayrows()       Function in Array.prg
  3618. *--               MUSCLICK.BIN      Binary mouse-event handler
  3619. *--               CWnSize()         Function to find window size
  3620. *--               CWnDecode()       Function to decode the above
  3621. *--               YnMouse()         Yesno function for mouse
  3622. *--               NormColors()      Function to return normal colors
  3623. *--               HighColors()      Function to return highlight colors
  3624. *--               ForeColor()       Function to return foreground color
  3625. *--
  3626. *-- Called by...: Any
  3627. *-- Usage.......: DO Multipick WITH <cArray>,<nDown>,<nLast>,<nRows>,;
  3628. *--                                 <nLength>[, <cColors> [, <cCheck>]]
  3629. *-- Example.....: DO Multipick WITH "Myarray",3,15,10,18,"RG+/G,N/W",;
  3630. *--                                 chr(2) 
  3631. *-- Parameters..: cArray      = Name of the array of selectable items.
  3632. *--                             See Notes, above, for required 
  3633. *--                             structure.
  3634. *--               nDown       = first useable row of window
  3635. *--               nLast       = last useable row of window
  3636. *--               nRows       = number of items to show on screen at 
  3637. *--                             once
  3638. *--               nLength     = maximum length of prompts
  3639. *--               cColors     = optional, colors to use for 
  3640. *--                             noncurrent and current items.  
  3641. *--                             Default is NORMAL and HIGHLIGHT colors 
  3642. *--                             for the current window.
  3643. *--                             Pass default as .F. if cCheck is 
  3644. *--                             included.
  3645. *--               cCheck      = optional, character to use to show 
  3646. *--                             selection. Default is "Ëš".  See 
  3647. *--                             "cBox" variables in the procedure for
  3648. *--                             bracketing characters.
  3649. *-- Also uses...: global numeric variable nG_MusClic, giving the inkey()
  3650. *--               value of the character "keyboarded" by a mouse click.
  3651. *--               If this variable does not exist, mouse support is 
  3652. *--               absent.
  3653. *-- Side effects: On return, the values of the second column of the 
  3654. *--               array are .T. or .F. in accordance with selections 
  3655. *--               made.
  3656. *-- Special note: The CWnSize function called by this routine uses
  3657. *--               VDCURSOR.BIN, which must be available for this routine
  3658. *--               to work, and disables any ON ERROR trap.
  3659. *-----------------------------------------------------------------------
  3660.  
  3661.    parameters cArray, nDown, nLast, nRows, nLength, cColors, cCheck
  3662.    private cChar, cCols, cNorm, cHigh, nAt, nTop, nKey, cBoxl, ;
  3663.            cBoxr 
  3664.    private nElems, lGotMouse, nMTop, nMBot, nMLeft, nMRight, cCols
  3665.    private cMrow, cMcol, nMrow, nMcol, cEsc, cWin, nWinTop, ;
  3666.            nWinLeft
  3667.    private nWinBot, nWinRight, nK, cK, cTemp, nX, cQuit, nRo, ;
  3668.            lOnPicks, lOk
  3669.  
  3670.    *  These "symbolic constants" are C-style, just to avoid "magic
  3671.    *  numbers" scattered throughout the routine.  Of course, they
  3672.    *  may also slow it down absent a true compiler
  3673.    private NBOXLEN, NEXTRAROWS, NPADLEN, NTWOPADS
  3674.    m->nBoxLen    =  6    && length of the "[ Ëš ] " structure
  3675.    m->nExtraRows =  4    && blank row at top, 3 rows for quit pads
  3676.    m->nPadLen    =  6    && length of the OK and Cancel pads
  3677.    m->nTwoPads   = 13    && length of two pads and a space between
  3678.  
  3679.    * set escape
  3680.    cEsc = set("ESCAPE")
  3681.    set escape off
  3682.  
  3683.    * set delimiter chars
  3684.    m->cBoxL = "[ "
  3685.    m->cBoxR = " ] "
  3686.  
  3687.    * set colors if specified
  3688.    if type( "cColors" ) = "C"
  3689.       m->cCols = m->cColors
  3690.    else
  3691.       m->cCols = set( "ATTRIBUTES" )
  3692.       m->cCols = left( m->cCols, at( "&", m->cCols ) - 2 )
  3693.    endif
  3694.    m->cNorm = NormColors( m->cCols )
  3695.    m->cHigh = HighColors( m->cCols )
  3696.    * set up quit pad colors
  3697.    m->cQuit = m->cHigh
  3698.  
  3699.    * set checkmark char, default is "Ëš" ( chr( 251 ) )
  3700.    m->cChar = iif( type( "cCheck" ) # "L", m->cCheck, "Ëš" )
  3701.  
  3702.    * calculate array rows and set up temporary array for restoration
  3703.    m->nElems = arrayrows( m->cArray )
  3704.    declare cTemp[ m->nElems ]
  3705.    m->nX = 1
  3706.    do while m->nX <= m->nElems
  3707.       cTemp[ m->nX ] = &cArray.[ m->nX, 2 ]
  3708.       m->nX = m->nX + 1
  3709.    enddo
  3710.  
  3711.    *  find borders of current window and determine centering offset
  3712.    m->cWin = cWnSize()
  3713.    if len( m->cWin ) > 0
  3714.       m->nWinTop   = cWnDecode( m->cWin, "T" )
  3715.       m->nWinLeft  = cWnDecode( m->cWin, "L" )
  3716.       m->nWinBot   = cWnDecode( m->cWin, "B" )
  3717.       m->nWinRight = cWnDecode( m->cWin, "R" )
  3718.    else
  3719.       activate screen
  3720.       ? "Can't find VDCURSOR.BIN - aborting"
  3721.       wait
  3722.       cancel
  3723.    endif
  3724.    m->nRight = int( ( m->nWinRight - m->nWinLeft - m->nBoxLen - ;
  3725.                       m->nLength ) / 2 )
  3726.    m->nCkCol = m->nRight + 2
  3727.  
  3728.    *  we need at least 13 columns for the quit pads, and enough for
  3729.    *  the checkbox table itself
  3730.    if m->nWinRight - m->nWinLeft < max( m->nTwoPads, ;
  3731.                      m->nBoxLen + m->nLength )
  3732.       activate screen
  3733.       ? "Too few columns in this window - aborting"
  3734.       wait
  3735.       cancel
  3736.    endif
  3737.  
  3738.    *  determine rows to use if window is small
  3739.    m->nRo = min( m->nRows, min( m->nLast - m->nDown,;
  3740.                  m->nWinBot - m->nWinTop - m->nExtraRows ) )
  3741.    if m->nRo < 1
  3742.       activate screen
  3743.       ? "Too few rows in this window - aborting"
  3744.       wait
  3745.       cancel
  3746.    endif
  3747.  
  3748.    * test for mouse support and set boundaries of active click area
  3749.    * nMx variables represent absolute screen positions of the edges
  3750.    * of the checkbox table
  3751.    m->lGotMouse = .F.
  3752.    if type( "nG_MusClick" ) = "N"
  3753.       m->lGotMouse = .T.
  3754.       m->nMTop   = m->nWinTop +  m->nDown - 1    && row above table
  3755.       m->nMLeft  = m->nWinLeft + m->nRight       && left edge of table
  3756.       m->nMBot   = m->nMTop + m->nRo + 1         && row below table
  3757.       m->nMRight = m->nMLeft + m->nBoxLen + m->nLength - 1 && right edge
  3758.    endif
  3759.  
  3760.    * position quit pads ( they are displayed by Smultpick )
  3761.    * nLpad and nRpad are column offsets within the active window
  3762.    * of the two pads, "  OK  " and "Cancel"
  3763.    if m->nPadLen + m->nLength > m->nTwoPads
  3764.       m->nLPad = m->nRight
  3765.    else
  3766.       m->nLPad = int( ( m->nWinRight - m->nWinLeft ) / 4 ) - ;
  3767.                       ( m->nPadLen / 2 )
  3768.    endif
  3769.    m->nRPad = m->nWinRight - m->nWinLeft - m->nPadLen - m->nLPad
  3770.  
  3771.    * initialize display as if "Home" had been pressed
  3772.    * nTop is the index into the array of the element to be shown
  3773.    *   on the top row of the table
  3774.    * nHigh is the index into the array of the element to be shown
  3775.    *   highlighted ( the current element )
  3776.    * lOnPicks is the "focus"; .T. means we are in the pick table,
  3777.    *   not on the quit pads
  3778.    m->nTop = 1
  3779.    m->nHigh = m->nTop
  3780.    keyboard "{Home}"
  3781.    m->lOnPicks = .T.
  3782.  
  3783.    * commence main key-handling loop
  3784.    do while .T.
  3785.       m->nKey = inkey()
  3786.       if m->nKey = 0
  3787.          loop
  3788.       endif
  3789.       do case
  3790.          case m->nKey = 23      && Ctrl-End
  3791.             exit
  3792.          case m->nKey = 27      && Escape
  3793.             if YesQuit()
  3794.                exit
  3795.             endif
  3796.          case m->nKey = 79 .or. m->nKey = 111   && 'O' or 'o'
  3797.             exit
  3798.          case m->nKey = 67 .or. m->nKey = 99    && 'C' or 'c'
  3799.             if YesQuit()
  3800.                exit
  3801.              endif
  3802.          case m->nKey = 9                    && Tab
  3803.             if m->lOnPicks
  3804.                lOk = .T.                    && default tab is "OK"
  3805.                @ row(), m->nRight say m->cBoxL + ;
  3806.                     iif( &cArray.[ m->nHigh, 2], ;
  3807.                     m->cChar, " " ) + m->cBoxR color &cNorm.
  3808.                @ row(), col() say left( &cArray.[ m->nHigh, 1 ] ;
  3809.                    + space( m->nLength ), m->nLength ) color &cNorm.
  3810.                @ m->nLast, m->nLPad + m->nPadLen / 2 say ""
  3811.             else
  3812.                do SmultPick
  3813.             endif
  3814.             m->lOnPicks = .not. m->lOnPicks
  3815.          case m->lGotMouse .and. m->nKey = nG_MusClick  && mouse click
  3816.             store chr(255) to m->cMRow, m->cMCol
  3817.             call MUSCLICK with m->cMRow, m->cMCol
  3818.             m->nMRow = asc( m->cMRow )
  3819.             m->nMCol = asc( m->cMCol )
  3820.             if m->nMRow >= m->nMTop .and. m->nMRow <= m->nMBot .and. ;
  3821.                m->nMCol >= m->nMLeft .and. m->nMCol <= m->nMRight   
  3822.                                                        && in active area
  3823.                m->nAt = m->nHigh - m->nTop + m->nMTop + 1
  3824.                do case
  3825.                   case m->nMRow = m->nAt
  3826.                      keyboard chr( 13 )
  3827.                   case m->nMRow = m->nMTop
  3828.                      keyboard "{PgUp}"
  3829.                   case m->nMRow = m->nMBot
  3830.                      keyboard "{PgDn}"
  3831.                   case m->nMRow > m->nAt
  3832.                      do while m->nAt < m->nMRow
  3833.                         keyboard "{DNARROW}"
  3834.                         m->nAt = m->nAt + 1
  3835.                      enddo
  3836.                   case m->nMRow < m->nAt
  3837.                      do while m->nAt > m->nMRow
  3838.                         keyboard "{UPARROW}"
  3839.                         m->nAt = m->nAt - 1
  3840.                      enddo
  3841.                endcase
  3842.             else
  3843.                * if it was on a pad
  3844.                if m->nMRow = m->nWinTop + m->nLast
  3845.                   if m->nMCol >= m->nWinLeft + m->nLPad .and. ;
  3846.                      m->nMCol < m->nWinLeft + ;
  3847.                      m->nLPad + m->nPadLen
  3848.                     keyboard "O"
  3849.                     loop
  3850.                   endif
  3851.                   if m->nMCol >= m->nWinLeft + m->nRPad .and.;
  3852.                      m->nMCol < m->nWinLeft + ;
  3853.                      m->nRPad + m->nPadLen
  3854.                     keyboard "C"
  3855.                     loop
  3856.                   endif
  3857.                endif
  3858.                keyboard "{Esc}"
  3859.             endif
  3860.          otherwise
  3861.             if m->lOnPicks
  3862.                do case
  3863.                   case m->nKey = 26      && Home
  3864.                      m->nTop = 1
  3865.                      m->nHigh = m->nTop
  3866.                      do SMultPick
  3867.                   case m->nKey = 2       && End
  3868.                       m->nTop = m->nElems - m->nRo + 1
  3869.                       m->nHigh = m->nElems
  3870.                       do SMultPick
  3871.                   case m->nKey = 24        && down arrow
  3872.                       if m->nHigh = m->nTop + m->nRo - 1 .or. ;
  3873.                          m->nHigh = m->nElems
  3874.                          keyboard "{PgDn}"
  3875.                        else
  3876.                           @ m->nHigh - m->nTop + m->nDown,;
  3877.                             m->nRight say ""
  3878.                           @ row(), m->nRight say m->cBoxL + ;
  3879.                             iif( &cArray.[ m->nHigh, 2], ;
  3880.                             m->cChar, " " ) + m->cBoxR color &cNorm.
  3881.                           @ row(), col() say ;
  3882.                             left( &cArray.[ m->nHigh, 1 ] ;
  3883.                             + space( m->nLength ), m->nLength ) ;
  3884.                             color &cNorm.
  3885.                           m->nHigh = m->nHigh + 1
  3886.                           @ row() + 1, m->nRight say m->cBoxL + ;
  3887.                             iif( &cArray.[ m->nHigh, 2], ;
  3888.                             m->cChar, " " ) +m->cBoxR color &cHigh.
  3889.                           @ row(), col() say ;
  3890.                             left( &cArray.[ m->nHigh, 1 ] ;
  3891.                             + space( m->nLength ), m->nLength );
  3892.                             color &cHigh.
  3893.                           @ row(), m->nCkCol say ""
  3894.                        endif
  3895.                   case m->nKey = 5         && up arrow
  3896.                      if m->nHigh = m->nTop
  3897.                         keyboard "{PgUp}"
  3898.                      else
  3899.                         @ m->nHigh - m->nTop + m->nDown, ;
  3900.                           m->nRight say ""
  3901.                         @ row(), m->nRight say m->cBoxL + ;
  3902.                           iif( &cArray.[ m->nHigh, 2], ;
  3903.                           m->cChar, " " ) + m->cBoxR color &cNorm.
  3904.                         @ row(), col() say ;
  3905.                           left( &cArray.[ m->nHigh, 1 ] ;
  3906.                           + space( m->nLength ), m->nLength );
  3907.                           color &cNorm.
  3908.                         m->nHigh = max( 1, m->nHigh - 1 )
  3909.                         @ row() - 1, m->nRight say m->cBoxL +;
  3910.                           iif( &cArray.[ m->nHigh, 2], ;
  3911.                           m->cChar, " " ) + m->cBoxR color &cHigh.
  3912.                         @ row(), col() say ;
  3913.                           left( &cArray.[ m->nHigh, 1 ] ;
  3914.                           + space( m->nLength ), m->nLength );
  3915.                           color &cHigh.
  3916.                         @ row(), m->nCkCol say ""
  3917.                      endif
  3918.                    case m->nKey = 32 .or. m->nKey = 13  
  3919.                                        && space and enter are toggles
  3920.                      &cArray.[ m->nHigh, 2 ] = .not. ;
  3921.                                         &cArray[ m->nHigh, 2 ]
  3922.                      @ row(), m->nCkCol say ;
  3923.                        iif( &cArray.[ m->nHigh, 2], m->cChar, " " ) ;
  3924.                        color &cHigh.
  3925.                      @ row(), m->nCkCol say ""
  3926.                   case m->nKey = 3      && PgDn
  3927.                      if m->nHigh = m->nTop + m->nRo - 1 .or.;
  3928.                         m->nHigh = m->nElems
  3929.                         m->nTop = min( m->nHigh, m->nElems - ;
  3930.                                        m->nRows + 1 )
  3931.                         do SmultPick
  3932.                      else
  3933.                         @ row(), m->nRight say m->cBoxL +;
  3934.                           iif( &cArray.[ m->nHigh, 2], ;
  3935.                           m->cChar, " " ) + m->cBoxR color &cNorm.
  3936.                         @ row(), col() say left( &cArray.[ m->nHigh, 1];
  3937.                            + space( m->nLength ), m->nLength );
  3938.                            color &cNorm.
  3939.                         m->nHigh = m->nTop + m->nRo - 1
  3940.                         @ m->nDown + m->nRo - 1, m->nRight say ""
  3941.                         @ row(), m->nRight say m->cBoxL + ;
  3942.                           iif( &cArray.[ m->nHigh, 2], ;
  3943.                           m->cChar, " " ) + m->cBoxR color &cHigh.
  3944.                         @ row(), col() say left( &cArray.[ m->nHigh, 1];
  3945.                            + space( m->nLength ), m->nLength ) ;
  3946.                            color &cHigh.
  3947.                         @ row(), m->nCkCol say ""
  3948.                      endif
  3949.                   case m->nKey = 18      && PgUp
  3950.                      if m->nHigh = m->nTop
  3951.                         m->nTop = max( 1, m->nHigh - m->nRo + 1 )
  3952.                         do SmultPick
  3953.                      else
  3954.                         m->nHigh = m->nTop
  3955.                         @ m->nDown, m->nRight say ""
  3956.                         @ row(), m->nRight say m->cBoxL +;
  3957.                           iif( &cArray.[ m->nHigh, 2], ;
  3958.                           m->cChar, " " ) + m->cBoxR color &cHigh.
  3959.                         @ row(), col() say left( &cArray.[ m->nHigh, 1];
  3960.                            + space( m->nLength ), m->nLength ) ;
  3961.                            color &cHigh.
  3962.                         @ row(), m->nCkCol say ""
  3963.                      endif
  3964.                endcase
  3965.             else
  3966.                do case
  3967.                   case m->nKey = 32 .or. m->nKey = 4 .or. m->nKey = 19  
  3968.                                            && space, r & l
  3969.                      m->lOK = .not. m->lOK
  3970.                      @ m->nLast, iif( m->lOK, m->nLPad, m->nRPad );
  3971.                        + m->nPadLen / 2 say ""
  3972.                   case m->nKey = 13        && and enter quits
  3973.                      if m->lOK
  3974.                         keyboard "{CTRL-END}"
  3975.                      else
  3976.                         keyboard "{ESC}"
  3977.                      endif
  3978.                endcase
  3979.             endif
  3980.          endcase
  3981.       enddo
  3982.  
  3983.       if m->cEsc ="ON"
  3984.          set escape on
  3985.       endif
  3986.  
  3987. RETURN
  3988. *-- EoP: MultiPick
  3989.  
  3990. FUNCTION CheckBox2
  3991. *-----------------------------------------------------------------------
  3992. *-- Programmer..: Adam L. Menkes (BORLAND TECHNICAL SUPPORT)
  3993. *-- Date........: 06/01/1992
  3994. *-- Notes.......: This routine brings up a one-line message, allows the 
  3995. *--               user to click mouse/press <Space> on it, to change 
  3996. *--               status. Pressing <Enter>/<Esc> chooses the current 
  3997. *--               setting ...
  3998. *-- Written for.: dBASE IV, 1.5
  3999. *-- Rev. History: 06/01/1992 -- Original Release
  4000. *-- Calls.......: None
  4001. *-- Called by...: Any
  4002. *-- Usage.......: CheckBox2(<lVar>,"<cTitle>",<nRow>,<nCol>,<nASCII>)
  4003. *-- Example.....: lX = CheckBox2(.t.,"OK as is?",9,10,4)
  4004. *-- Returns.....: Logical
  4005. *-- Parameters..: lVar     = On or Off to start? (.t.=on, .f.=off)
  4006. *--               cTitle   = Title/Message
  4007. *--               nRow     = Row to place this
  4008. *--               nCol     = Column ...
  4009. *--               nASCII   = ascii character to use in box. (Optional)
  4010. *--                          Default is 251 (Ëš). Other suggestions 
  4011. *--                          include:
  4012. *--                          4 (diamond), 176 (∞), 177 (±), 178 (≤),
  4013. *--                          219 (€), 249 (˘), 250 (Ë™), 254 (Ë›)
  4014. *--                          (Check out the ASCII chart in the 
  4015. *--                          language ref.)
  4016. *-----------------------------------------------------------------------
  4017.  
  4018.    parameters lVar, cTitle, nRow, nCol, nASCII
  4019.    
  4020.    *-- if parameter is left blank, assign 251 (Ëš)
  4021.    m->nASCII = iif(pCount() = 5, m->nASCII, 251)
  4022.    
  4023.    define menu mCheck
  4024.    
  4025.    *-- loop until user does something, or presses <Esc>
  4026.    do while .t.
  4027.    
  4028.       *-- define the menu pad ...
  4029.       define pad pCheck1 of mCheck at m->nRow,m->nCol prompt;
  4030.          "["+iif(m->lVar,chr(m->nASCII)," ")+"] "+m->cTitle
  4031.       on selection pad pCheck1 of mCheck deactivate menu
  4032.       
  4033.       *-- when user presses <Enter> turn it all off ... (send <Esc> ...)
  4034.       on key label ctrl-m keyboard "{27}"
  4035.       
  4036.       *-- start 'er up
  4037.       activate menu mCheck
  4038.       
  4039.       *-- (<Esc> or <Enter>)
  4040.       if lastkey() = 27
  4041.          exit
  4042.       endif
  4043.       
  4044.       m->lVar = .not. m->lVar   && set to opposite of current setting
  4045.       
  4046.    enddo
  4047.    
  4048.    *-- reset environment/release things
  4049.    on key label ctrl-m
  4050.    release menu mCheck
  4051.  
  4052. RETURN m->lVar
  4053. *-- EoF: CheckBox2()
  4054.  
  4055. Function CheckBx1
  4056. *-----------------------------------------------------------------------
  4057. *-- Programmer..: Adam L. Menkes (BORLAND TECHNICAL SUPPORT)
  4058. *-- Date........: 06/01/1992
  4059. *-- Notes.......: This routine brings up a one-line message, allows the 
  4060. *--               user to click mouse/press <Space> on it, to change 
  4061. *--               status. Pressing <Enter>/<Esc> chooses the current 
  4062. *--               setting ...
  4063. *--               This one is different, in that it does not use a menu 
  4064. *--               to accomplish it's ends, but uses instead a memvar, 
  4065. *--               with @/GET/READ and a picture using the multiple 
  4066. *--               choice ("@M") function.
  4067. *-- Written for.: dBASE IV, 1.5
  4068. *-- Rev. History: 06/01/1992 -- Original
  4069. *-- Calls.......: None
  4070. *-- Called by...: Any
  4071. *-- Usage.......: CheckBx1(<lVar>,"<cTitle>",<nRow>,<nCol>)
  4072. *-- Example.....: lX = CheckBx1(.t.,"OK as is?",9,10)
  4073. *-- Returns.....: Logical
  4074. *-- Parameters..: lVar     = On or Off to start? (.t.=on, .f.=off)
  4075. *--               cTitle   = Title/Message
  4076. *--               nRow     = Row to place this
  4077. *--               nCol     = Column ...
  4078. *-----------------------------------------------------------------------
  4079.  
  4080.    parameters lVar, cTitle, nRow, nCol
  4081.    
  4082.    *-- save parts of environment ...
  4083.    m->cFormat = set("FORMAT")
  4084.    set format to
  4085.    m->cCursor = set("CURSOR")
  4086.    set cursor off
  4087.    
  4088.    *-- define starting value of cVar ... 
  4089.    *-- (this is ASCII 255, Ëš, ASCII 255, if lVar = .t., 3 spaces 
  4090.    *-- if lVar = .f.)
  4091.    m->cVar = iif(m->lVar,chr(255)+chr(251)+chr(255),space(3))
  4092.    
  4093.    *-- display/get, using picture
  4094.    @m->nRow,m->nCol get m->cVar picture "@M ,ˇ˚ˇ"
  4095.  
  4096.    *-- this picture is: space, comma, chr(255), chr(251), chr(255).
  4097.    @m->nRow,m->nCol + 4 say m->cTitle
  4098.    
  4099.    READ
  4100.    
  4101.    *-- reset environment
  4102.    set format to &cFormat.
  4103.    set cursor &cCursor.
  4104.    
  4105. RETURN .not. (m->cVar = chr(32))   && not a space
  4106. *-- EoF: CheckBx1()
  4107.  
  4108. FUNCTION RadioBut
  4109. *-----------------------------------------------------------------------
  4110. *-- Programmer..: Adam L. Menkes (BORLAND TECHNICAL SUPPORT)
  4111. *-- Date........: 06/01/1992
  4112. *-- Notes.......: This is a Radio Button routine.  NOTE that the array 
  4113. *--               called as cArray below must be a character array (i.e.
  4114. *--               all data must be character data ...).
  4115. *-- Written for.: dBASE IV, 1.5
  4116. *-- Rev. History: 06/01/1992 -- Original
  4117. *-- Calls.......: ArrayRows()          Function in WINDOWS.PRG
  4118. *--               TmpRadio             Procedure in WINDOWS.PRG
  4119. *-- Called by...: None
  4120. *-- Usage.......: RadioBut("<cArray>",<nRow>,<nCol>,<nDefPad>,<nASCII>)
  4121. *-- Example.....: nReturn =  RadioBut("aTest",5,10,1,15)
  4122. *-- Returns.....: Numeric (Array Index of item selected)
  4123. *-- Parameters..: cArray  = Name of Array (Character data)
  4124. *--               nRow    = Row for coordinates ... (start position)
  4125. *--               nCol    = Column for same
  4126. *--               nDefPad = Default Pad number
  4127. *--               nASCII  = ASCII character to use as 'button' 
  4128. *--                        (Optional ...)
  4129. *--                   try: 4 (Diamond), 9 (Circle), 15 (splot), 42 (*),
  4130. *--                        249 (˘),  251 (Ëš) or 254 (Ë›) ...
  4131. *-----------------------------------------------------------------------
  4132.    
  4133.    parameters cArray, nRow, nCol, nDefPad, nASCII
  4134.    
  4135.    define menu mRadio
  4136.    public aTmpRadio, nARows, nPad
  4137.    
  4138.    *-- get number of items to display
  4139.    m->nARows = ArrayRows(m->cArray)
  4140.    
  4141.    *-- set character for 'button'
  4142.    m->nASCII = iif(PCOUNT() <= 4,4,m->nASCII) && default is a 'diamond'
  4143.    
  4144.    *-- start definitions ...
  4145.    m->cPad = iif(pcount() => 4 .and. m->nDefPad # 0,;
  4146.                                      ltrim(str(m->nDefPad)),"1")
  4147.    m->nCol = iif(pcount() <= 2,10,m->nCol)
  4148.    m->nRow = iif(pCount() <= 1,5,m->nRow)
  4149.    
  4150.    *-- here we get the largest item in the array ...
  4151.    m->nX = 1
  4152.    m->nLongest = 1
  4153.    do while m->nX <= m->nARows
  4154.       m->nLongest = max(m->nLongest,len(trim(&cArray.[m->nX])))
  4155.       m->nX = m->nX + 1
  4156.    enddo
  4157.    
  4158.    *-- define a temporary array ...
  4159.    declare aTmpRadio[m->nARows]
  4160.    
  4161.    on key label ctrl-m keyboard "{27}"  && close down if <Enter> ...
  4162.    
  4163.    m->cX = "1"
  4164.    do while .t.
  4165.       
  4166.       *-- define menu pads
  4167.       do while val(m->cX) <= m->nARows
  4168.          define pad button&cX. of mRadio at m->nRow - 1 + ;
  4169.             val(m->cX),m->nCol;
  4170.             prompt "("+ iif(aTmpRadio[val(m->cX)] .or. m->cPad = m->cX,;
  4171.             chr(m->nASCII)," ")+") "+trim(&cArray[val(m->cX)])+;
  4172.             space(m->nLongest-len(trim(&cArray[val(m->cX)])))
  4173.          on selection pad button&cX. of mRadio deactivate menu
  4174.          m->cX = ltrim(str(val(m->cX)+1))
  4175.       enddo
  4176.    
  4177.       *-- start 'er up
  4178.       activate menu mRadio pad button&nPad.
  4179.       *-- if <Esc> (or <Enter>), we're done ...
  4180.       if lastkey() = 27
  4181.          nPad = substr(pad(),7)
  4182.          exit
  4183.       else
  4184.          *-- if not, perform routine below to reset the temp array ...
  4185.          do TmpRadio
  4186.       endif
  4187.    enddo
  4188.    
  4189.    *-- cleanup
  4190.    on key label ctrl-m
  4191.    m->nY = 1
  4192.    do while m->nY <= m->nARows .and. .not. aTmpRadio[m->nY]
  4193.       m->nY = m->nY + 1
  4194.    enddo
  4195.    release aTmpRadio, nPad
  4196.    release menu mRadio
  4197.  
  4198. RETURN iif(m->nY > m->nARows, 0, m->nY)
  4199. *-- EoF: RadioBut()
  4200.  
  4201. PROCEDURE TmpRadio
  4202. *-----------------------------------------------------------------------
  4203. *-- Programmer..: Adam L. Menkes (BORLAND TECHNICAL SUPPORT)
  4204. *-- Date........: 06/01/1992
  4205. *-- Notes.......: Used to set/reset the temporary array aTmpRadio[] for 
  4206. *--               use in the RadioBut() function above.
  4207. *-- Written for.: dBASE IV, 1.5
  4208. *-- Rev. History: 06/01/1992 -- Original
  4209. *-- Calls.......: None
  4210. *-- Called by...: RadioBut()           Function in WINDOWS.PRG
  4211. *-- Usage.......: Do TmpRadio
  4212. *-- Example.....: Do TmpRadio
  4213. *-- Returns.....: None
  4214. *-- Parameters..: None
  4215. *-----------------------------------------------------------------------
  4216.    
  4217.    m->nPad = substr(pad(),7)
  4218.    m->nY = 1
  4219.    do while m->nY <= m->nARows
  4220.       aTmpRadio[m->nY] = .f.
  4221.       m->nY = m->nY + 1
  4222.    enddo
  4223.    aTmpRadio[val(m->nPad)] = .t.
  4224.    m->cX = "1"
  4225.  
  4226. RETURN
  4227. *-- EoP: TmpRadio
  4228.  
  4229. PROCEDURE BORD3D
  4230. *-----------------------------------------------------------------------
  4231. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  4232. *-- Date........: 03/15/1993
  4233. *-- Notes.......: Designed to take a dialog box that _doesn't_ have a 
  4234. *--               border defined (NONE), and is a grey box (i.e., 
  4235. *--               background is 'W' for color) and give a 3-d border 
  4236. *--               to it ...
  4237. *--               ASSUMPTION: Dialog box is defined in a window ... (not
  4238. *--               using @...FILL TO ... command)
  4239. *-- Written for.: dBASE IV, 1.5
  4240. *-- Rev. History: 03/15/1993 -- Original
  4241. *-- Calls.......: COLORBRK()           Function in PROC.PRG
  4242. *--               BackColor()          Function in COLOR.PRG
  4243. *-- Called by...: Any (Specifically YESNO4())
  4244. *-- Usage.......: Do Bord3D with <m->nHeight>,<nWidth>,<cColor>,<nStyle>
  4245. *-- Example.....: Do Bord3D with 9,40,cWind1,2
  4246. *-- Returns.....: None
  4247. *-- Parameters..: nHeight  = height of dialog box 
  4248. *--               nWidth   = Width of dialog box
  4249. *--               cColor   = Color settings used for dialog box -- 
  4250. *--                          requires at a minimum the colors for the 
  4251. *--                          text part (i.e, "rg+/r")
  4252. *--               nStyle   = 'Style' of border -- 1 = raised, 2 = inset
  4253. *-----------------------------------------------------------------------
  4254.  
  4255.    parameters nHeight, nWidth, cColor, nStyle
  4256.    private nHeight2, nWidth2
  4257.    
  4258.    m->cBorder = set("BORDER")       && save border setting
  4259.    set border to single             && must be single for this ...
  4260.    
  4261.    *-- figure out colors
  4262.    m->cTextColor = colorbrk(m->cColor,1)
  4263.    m->cBackColor = backcolor(m->cTextColor)
  4264.    m->cHighColor = "W+/"+m->cBackColor
  4265.    m->cShadColor = "N/"+m->cBackColor
  4266.    
  4267.    *-- if style is 1, we do the commands for a 'raised' border
  4268.    *-- if style is 2, we do an 'inset' border
  4269.    if m->nStyle < 1 .or. m->nStyle > 2  && if not 1 or 2 ...
  4270.       m->nStyle = 1
  4271.    endif
  4272.    
  4273.    if m->nStyle = 1
  4274.       *-- Outside of "border"
  4275.       @0,0 to 0,m->nWidth                    color &cHighColor. 
  4276.       @0,0 to m->nHeight, 0                  color &cHighColor.         
  4277.       @0,0       say chr(218)                color &cHighColor.     
  4278.       @m->nHeight,0 say chr(192)             color &cHighColor.   
  4279.       @0,m->nWidth   to m->nHeight,m->nWidth color &cShadColor. 
  4280.       @m->nHeight, 1 to m->nHeight,m->nWidth color &cShadColor. 
  4281.       @0,m->nWidth say chr(191)              color &cShadColor.        
  4282.       @m->nHeight,m->nWidth say chr(217)     color &cShadColor.     
  4283.       *-- inside of "border"
  4284.       m->nWidth2 = m->nWidth - 2
  4285.       m->nHeight2 = m->nHeight - 1
  4286.       @1,2 to 1,m->nWidth2                     color &cShadColor.      
  4287.       @1,2 to m->nHeight2,2                    color &cShadColor.     
  4288.       @1,2 say chr(218)                        color &cShadColor.         
  4289.       @m->nHeight2,2 say chr(192)              color &cShadColor.        
  4290.       @1,m->nWidth2 to m->nHeight2,m->nWidth2  color &cHighColor.  
  4291.       @m->nHeight2,3 to m->nHeight2,m->nWidth2 color &cHighColor.  
  4292.       @1,m->nWidth2 say chr(191)               color &cHighColor.              
  4293.       @m->nHeight2,m->nWidth2 say chr(217)     color &cHighColor. 
  4294.    
  4295.    else
  4296.       
  4297.       *-- Outside of "border"
  4298.       @0,0 to 0,m->nWidth                     color &cShadColor.         
  4299.       @0,0 to m->nHeight, 0                   color &cShadColor.           
  4300.       @0,0       say chr(218)                 color &cShadColor.     
  4301.       @m->nHeight,0 say chr(192)              color &cShadColor.     
  4302.       @0,m->nWidth   to m->nHeight,m->nWidth  color &cHighColor.
  4303.       @m->nHeight, 1 to m->nHeight,m->nWidth  color &cHighColor.
  4304.       @0,m->nWidth say chr(191)               color &cHighColor.       
  4305.       @m->nHeight,m->nWidth say chr(217)      color &cHighColor. 
  4306.    
  4307.       *-- inside of "border"
  4308.       m->nWidth2 = m->nWidth - 2
  4309.       m->nHeight2 = m->nHeight - 1
  4310.       @1,2 to 1,m->nWidth2                     color &cHighColor.       
  4311.       @1,2 to m->nHeight2,2                    color &cHighColor.       
  4312.       @1,2 say chr(218)                        color &cHighColor.              
  4313.       @m->nHeight2,2 say chr(192)              color &cHighColor.         
  4314.       @1,m->nWidth2 to m->nHeight2,m->nWidth2  color &cShadColor.   
  4315.       @m->nHeight2,3 to m->nHeight2,m->nWidth2 color &cShadColor.  
  4316.       @1,m->nWidth2 say chr(191)               color &cShadColor.         
  4317.       @m->nHeight2,m->nWidth2 say chr(217)     color &cShadColor.   
  4318.    
  4319.    endif
  4320.    
  4321.    *-- reset border
  4322.    set border to &cBorder.
  4323.  
  4324. RETURN
  4325. *-- EoP: Bord3D
  4326.  
  4327. PROCEDURE Bord3D2
  4328. *-----------------------------------------------------------------------
  4329. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  4330. *-- Date........: 03/18/1993
  4331. *-- Notes.......: This variation on BORD3D was written to deal with 
  4332. *--               items that are "filled", rather than windows, that 
  4333. *--               have a set edge. This one requires that the actual 
  4334. *--               coordinates get passed to it.
  4335. *-- Written for.: dBASE IV, 1.5
  4336. *-- Rev. History: 03/18/1993 -- Original
  4337. *-- Calls.......: None
  4338. *-- Called by...: Any
  4339. *-- Usage.......: Do Bord3D2 with <nTop>,<nLeft>,<nBottom>,<nRight>,;
  4340. *--                               <cColor>,<nStyle>
  4341. *-- Example.....: Do Bord3d2 with 0,15,4,60,cColor,1
  4342. *-- Returns.....: None
  4343. *-- Parameters..: nTop    = top row
  4344. *--               nLeft   = Left column
  4345. *--               nBottom = Bottom Row
  4346. *--               nRight  = Right Column
  4347. *--               cColor  = Color of area being filled
  4348. *--               nStyle  = type of 3-d border (1 = Raised, 2 = Inset)
  4349. *-----------------------------------------------------------------------
  4350.  
  4351.    parameters nTop,nLeft,nBottom,nRight,cColor,nStyle
  4352.  
  4353.    *-- deal with border ...
  4354.    *-- figure out colors
  4355.    m->cBackColor = backcolor(m->cColor)
  4356.    m->cHighColor = "W+/"+m->cBackColor
  4357.    m->cShadColor = "N/"+m->cBackColor
  4358.    
  4359.    *-- if style is 1, we do the commands for a 'raised' border
  4360.    *-- if style is 2, we do an 'inset' border
  4361.    if m->nStyle < 1 .or. m->nStyle > 2  && if not 1 or 2 ...
  4362.       m->nStyle = 1
  4363.    endif
  4364.    
  4365.    if m->nStyle = 1
  4366.       *-- RAISED Border
  4367.       *-- Outside of "border"
  4368.       @m->nTop,m->nLeft to m->nTop,m->nRight         color &cHighColor. 
  4369.       @m->nTop,m->nLeft to m->nBottom,m->nLeft       color &cHighColor.   
  4370.       @m->nTop,m->nLeft say chr(218)                 color &cHighColor.
  4371.       @m->nBottom,m->nLeft say chr(192)              color &cHighColor.
  4372.       @m->nTop,m->nRight to m->nBottom,m->nRight     color &cShadColor. 
  4373.       @m->nBottom,m->nLeft+1 to m->nBottom,m->nRight color &cShadColor. 
  4374.       @m->nTop,m->nRight say chr(191)                color &cShadColor. 
  4375.       @m->nBottom,m->nRight say chr(217)             color &cShadColor. 
  4376.    
  4377.       *-- inside of "border"
  4378.       @m->nTop+1,m->nLeft+2 to m->nTop+1,m->nRight-2 color &cShadColor. 
  4379.       @m->nTop+1,m->nLeft+2 to m->nBottom-1,m->nLeft+2 ;
  4380.                                                      color &cShadColor. 
  4381.       @m->nTop+1,m->nLeft+2 say chr(218)             color &cShadColor. 
  4382.       @m->nBottom-1,m->nLeft+2 say chr(192)          color &cShadColor. 
  4383.       @m->nTop+1,m->nRight-2 to m->nBottom-1,m->nRight-2;
  4384.                                                      color &cHighColor. 
  4385.       @m->nBottom-1,m->nLeft+3 to m->nBottom-1,m->nRight-2;
  4386.                                                      color &cHighColor. 
  4387.       @m->nTop+1,m->nRight-2 say chr(191)            color &cHighColor. 
  4388.       @m->nBottom-1,m->nRight-2 say chr(217)         color &cHighColor. 
  4389.    
  4390.    else
  4391.       *-- RECESSED Border
  4392.       *-- Outside of "border"
  4393.       @m->nTop,m->nLeft to m->nTop,m->nRight         color &cShadColor. 
  4394.       @m->nTop,m->nLeft to m->nBottom,m->nLeft       color &cShadColor.   
  4395.       @m->nTop,m->nLeft say chr(218)                 color &cShadColor. 
  4396.       @m->nBottom,m->nLeft say chr(192)              color &cShadColor. 
  4397.       @m->nTop,m->nRight to m->nBottom,m->nRight     color &cHighColor. 
  4398.       @m->nBottom,m->nLeft+1 to m->nBottom,m->nRight color &cHighColor. 
  4399.       @m->nTop,m->nRight say chr(191)                color &cHighColor. 
  4400.       @m->nBottom,m->nRight say chr(217)             color &cHighColor. 
  4401.    
  4402.       *-- inside of "border"
  4403.       @m->nTop+1,m->nLeft+2 to m->nTop+1,m->nRight-2  color &cHighColor. 
  4404.       @m->nTop+1,m->nLeft+2 to m->nBottom-1,m->nLeft+2; 
  4405.                                                       color &cHighColor.       
  4406.                                                       color &cHighColor.      
  4407.       @m->nBottom+1,m->nLeft+2 say chr(192)           color &cHighColor. 
  4408.       @m->nTop+1,m->nRight-2 to m->nBottom-1,m->nRight-2;
  4409.                                                       color &cShadColor. 
  4410.       @m->nBottom-1,m->nLeft+3 to m->nBottom-1,m->nRight-2 ;
  4411.                                                       color &cShadColor. 
  4412.       @m->nTop+1,m->nRight-2 say chr(191)             color &cShadColor.
  4413.       @m->nBottom-1,m->nRight-2 say chr(217)          color &cShadColor.
  4414.    
  4415.    endif
  4416.    
  4417.    *-- reset border
  4418.    set border to &cBorder.
  4419.    
  4420. RETURN
  4421. *-- EoP: Bord3D2
  4422.  
  4423. PROCEDURE Bord3D3
  4424. *-----------------------------------------------------------------------
  4425. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  4426. *-- Date........: 05/07/1993
  4427. *-- Notes.......: Designed to take a dialog box that _doesn't_ have a 
  4428. *--               border defined (NONE) and give a 3-d border to it ... 
  4429. *--               ASSUMPTION: Dialog box is defined in a window ... (not
  4430. *--               using @...FILL TO ... command)
  4431. *-- Written for.: dBASE IV, 1.5
  4432. *-- Rev. History: 03/15/1993 -- Original
  4433. *--               05/07/1993 -- Version to give a single-line border
  4434. *-- Calls.......: COLORBRK()           Function in PROC.PRG
  4435. *--               BackColor()          Function in COLOR.PRG
  4436. *-- Called by...: Any (Specifically YESNO4())
  4437. *-- Usage.......: Do Bord3D3 with <nHeight>,<nWidth>,<cColor>,;
  4438. *--                               <nStyle>
  4439. *-- Example.....: Do Bord3D3 with 9,40,cWind1,2
  4440. *-- Returns.....: None
  4441. *-- Parameters..: nHeight  = height of dialog box 
  4442. *--               nWidth   = Width of dialog box
  4443. *--               cColor   = Color settings used for dialog box -- 
  4444. *--                          requires at a minimum the colors for the
  4445. *--                          text part (i.e, "rg+/r")
  4446. *--               nStyle   = 'Style' of border -- 1 = raised, 2 = inset 
  4447. *-----------------------------------------------------------------------
  4448.  
  4449.    parameters nHeight, nWidth, cColor, nStyle
  4450.    private nHeight2, nWidth2
  4451.    
  4452.    m->cBorder = set("BORDER")    && save border setting
  4453.    set border to single          && must be single for this ...
  4454.    
  4455.    *-- figure out colors
  4456.    m->cTextColor = colorbrk(m->cColor,1)
  4457.    m->cBackColor = backcolor(m->cTextColor)
  4458.    m->cHighColor = "W+/"+m->cBackColor
  4459.    m->cShadColor = "N/"+m->cBackColor
  4460.    
  4461.    *-- if style is 1, we do the commands for a 'raised' border
  4462.    *-- if style is 2, we do an 'inset' border
  4463.    if m->nStyle < 1 .or. m->nStyle > 2  && if not 1 or 2 ...
  4464.       m->nStyle = 1
  4465.    endif
  4466.    
  4467.    if m->nStyle = 1
  4468.       *-- Outside of "border"
  4469.       @0,0 to 0,m->nWidth                    color &cHighColor.        
  4470.       @0,0 to m->nHeight, 0                  color &cHighColor.      
  4471.       @0,0       say chr(218)                color &cHighColor.    
  4472.       @m->nHeight,0 say chr(192)             color &cHighColor. 
  4473.       @0,m->nWidth   to m->nHeight,m->nWidth color &cShadColor. 
  4474.       @m->nHeight, 1 to m->nHeight,m->nWidth color &cShadColor. 
  4475.       @0,m->nWidth say chr(191)              color &cShadColor.        
  4476.       @m->nHeight,m->nWidth say chr(217)     color &cShadColor. 
  4477.    
  4478.    else
  4479.       
  4480.       *-- Outside of "border"
  4481.       @0,0 to 0,m->nWidth                    color &cShadColor.           
  4482.       @0,0 to m->nHeight, 0                  color &cShadColor.           
  4483.       @0,0       say chr(218)                color &cShadColor.       
  4484.       @m->nHeight,0 say chr(192)             color &cShadColor.    
  4485.       @0,m->nWidth   to m->nHeight,m->nWidth color &cHighColor.
  4486.       @m->nHeight, 1 to m->nHeight,m->nWidth color &cHighColor.
  4487.       @0,m->nWidth say chr(191)              color &cHighColor.        
  4488.       @m->nHeight,m->nWidth say chr(217)     color &cHighColor. 
  4489.    
  4490.    endif
  4491.    
  4492.    *-- reset border
  4493.    set border to &cBorder.
  4494.  
  4495. RETURN
  4496. *-- EoP: Bord3D3
  4497.  
  4498. PROCEDURE Bord3D4
  4499. *-----------------------------------------------------------------------
  4500. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  4501. *-- Date........: 05/07/1993
  4502. *-- Notes.......: This variation on BORD3D was written to deal with 
  4503. *--               items that are "filled", rather than windows, that 
  4504. *--               have a set edge. This one requires that the actual 
  4505. *--               coordinates get passed to it. This one is a single-
  4506. *--               line version of BORD3D2.
  4507. *-- Written for.: dBASE IV, 1.5
  4508. *-- Rev. History: 03/18/1993 -- Original
  4509. *--               05/07/1993 -- Single-Line Version
  4510. *-- Calls.......: None
  4511. *-- Called by...: Any
  4512. *-- Usage.......: Do Bord3D4 with <nTop>,<nLeft>,<nBottom>,<nRight>,;
  4513. *--                               <cColor>,<nStyle>
  4514. *-- Example.....: Do Bord3d4 with 0,15,4,60,cColor,1
  4515. *-- Returns.....: None
  4516. *-- Parameters..: nTop    = top row
  4517. *--               nLeft   = Left column
  4518. *--               nBottom = Bottom Row
  4519. *--               nRight  = Right Column
  4520. *--               cColor  = Color of area being filled
  4521. *--               nStyle  = type of 3-d border (1 = Raised, 2 = Inset)
  4522. *-----------------------------------------------------------------------
  4523.  
  4524.    parameters nTop,nLeft,nBottom,nRight,cColor,nStyle
  4525.  
  4526.    *-- deal with border ...
  4527.    m->cBorder = set("BORDER")
  4528.    
  4529.    *-- figure out colors
  4530.    m->cTextColor = colorbrk(m->cColor,1)
  4531.    m->cBackColor = backcolor(m->cTextColor)
  4532.    m->cHighColor = "W+/"+m->cBackColor
  4533.    m->cShadColor = "N/"+m->cBackColor
  4534.    
  4535.    *-- if style is 1, we do the commands for a 'raised' border
  4536.    *-- if style is 2, we do an 'inset' border
  4537.    if m->nStyle < 1 .or. m->nStyle > 2  && if not 1 or 2 ...
  4538.       m->nStyle = 1
  4539.    endif
  4540.    
  4541.    if m->nStyle = 1
  4542.       *-- RAISED Border
  4543.       *-- Outside of "border"
  4544.       @m->nTop,m->nLeft to m->nTop,m->nRight     color &cHighColor. 
  4545.       @m->nTop,m->nLeft to m->nBottom,m->nLeft   color &cHighColor. 
  4546.       @m->nTop,m->nLeft say chr(218)             color &cHighColor. 
  4547.       @m->nBottom,m->nLeft say chr(192)          color &cHighColor. 
  4548.       @m->nTop,m->nRight to m->nBottom,m->nRight color &cShadColor.
  4549.       @m->nBottom,m->nLeft+1 to m->nBottom,m->nRight color &cShadColor.
  4550.       @m->nTop,m->nRight say chr(191)            color &cShadColor. 
  4551.       @m->nBottom,m->nRight say chr(217)         color &cShadColor. 
  4552.    
  4553.    else
  4554.       *-- RECESSED Border
  4555.       *-- Outside of "border"
  4556.       @m->nTop,m->nLeft to m->nTop,m->nRight     color &cShadColor.
  4557.       @m->nTop,m->nLeft to m->nBottom,m->nLeft   color &cShadColor.
  4558.       @m->nTop,m->nLeft say chr(218)             color &cShadColor.
  4559.       @m->nBottom,m->nLeft say chr(192)          color &cShadColor.
  4560.       @m->nTop,m->nRight to m->nBottom,m->nRight color &cHighColor.
  4561.       @m->nBottom,m->nLeft+1 to m->nBottom,m->nRight color &cHighColor.
  4562.       @m->nTop,m->nRight say chr(191)            color &cHighColor. 
  4563.       @m->nBottom,m->nRight say chr(217)         color &cHighColor. 
  4564.    
  4565.    endif
  4566.    
  4567.    *-- reset border
  4568.    set border to &cBorder.
  4569.    
  4570. RETURN
  4571. *-- EoP: Bord3D4
  4572.  
  4573. PROCEDURE Bord3D5
  4574. *-----------------------------------------------------------------------
  4575. *-- Programmer..: Kenneth J. Mayer (CIS: 71333,1030)
  4576. *-- Date........: 06/02/1993
  4577. *-- Notes.......: This is an attempt to combine the 3-D border routines
  4578. *--               (BORD3D through BORD3D4) -- allowing a selection 
  4579. *--               between four border styles ... 
  4580. *-- Written for.: dBASE IV, 1.5 or later
  4581. *-- Rev. History: 06/02/1993
  4582. *-- Calls.......: None
  4583. *-- Called by...: Any (specifically YESNO6())
  4584. *-- Usage.......: do Bord3D5 with <nULR>,<nULC>,<nBRR>,<nBRC>,<cColor>,;
  4585. *--                               <nStyle>
  4586. *-- Example.....: do Bord3D5 with 0,0,15,60,2
  4587. *-- Returns.....: None
  4588. *-- Parameters..: nULR   = Upper Left Row (Starting Coordinates)
  4589. *--               nULC   = Upper Left Column
  4590. *--               nBRR   = Bottom Right Row (Ending Coordinates)
  4591. *--               nBRC   = Bottom Right Column
  4592. *--               cColor = Colors of Window/Box ...
  4593. *--               nStyle = Border style:
  4594. *--                        1 = Double, Raised
  4595. *--                        2 = Double, Recessed
  4596. *--                        3 = Single, Raised
  4597. *--                        4 = Single, Recessed
  4598. *-----------------------------------------------------------------------
  4599.  
  4600.    parameters nULR, nULC, nBRR, nBRC, cColor, nStyle
  4601.    private cBorder,cBackColor,cHighColor,cShadColor
  4602.    
  4603.    *-- deal with border ...
  4604.    m->cBorder = set("BORDER")
  4605.    set border to single
  4606.    
  4607.    *-- figure out colors
  4608.    m->cBackColor = backcolor(m->cColor)
  4609.    m->cHighColor = "W+/"+m->cBackColor
  4610.    m->cShadColor = "N/"+m->cBackColor
  4611.    
  4612.    if m->nStyle < 1 .or. m->nStyle > 4  && if not 1 through 4 ...
  4613.       m->nStyle = 1
  4614.    endif
  4615.    
  4616.    do case
  4617.       case m->nStyle = 1
  4618.       
  4619.          *-- Raised DOUBLE Border
  4620.          *-- Outside of "border"
  4621.          @m->nULR,m->nULC to m->nULR,m->nBRC   color &cHighColor. 
  4622.          @m->nULR,m->nULC to m->nBRR,m->nULC   color &cHighColor. 
  4623.          @m->nULR,m->nULC say chr(218)         color &cHighColor. 
  4624.          @m->nBRR,m->nULC say chr(192)         color &cHighColor. 
  4625.          @m->nULR,m->nBRC to m->nBRR,m->nBRC   color &cShadColor. 
  4626.          @m->nBRR,m->nULC+1 to m->nBRR,m->nBRC color &cShadColor. 
  4627.          @m->nULR,m->nBRC say chr(191)         color &cShadColor. 
  4628.          @m->nBRR,m->nBRC say chr(217)         color &cShadColor. 
  4629.       
  4630.          *-- inside of "border"
  4631.          @m->nULR+1,m->nULC+2 to m->nULR+1,m->nBRC-2 color &cShadColor. 
  4632.          @m->nULR+1,m->nULC+2 to m->nBRR-1,m->nULC+2 color &cShadColor. 
  4633.          @m->nULR+1,m->nULC+2 say chr(218)           color &cShadColor. 
  4634.          @m->nBRR-1,m->nULC+2 say chr(192)           color &cShadColor. 
  4635.          @m->nULR+1,m->nBRC-2 to m->nBRR-1,m->nBRC-2 color &cHighColor. 
  4636.          @m->nBRR-1,m->nULC+3 to m->nBRR-1,m->nBRC-2 color &cHighColor. 
  4637.          @m->nULR+1,m->nBRC-2 say chr(191)           color &cHighColor. 
  4638.          @m->nBRR-1,m->nBRC-2 say chr(217)           color &cHighColor. 
  4639.    
  4640.       case m->nStyle = 2
  4641.          
  4642.          *-- Recessed DOUBLE Border
  4643.          *-- Outside of "border"
  4644.          @m->nULR,m->nULC to m->nULR,m->nBRC   color &cShadColor.
  4645.          @m->nULR,m->nULC to m->nBRR,m->nULC   color &cShadColor.
  4646.          @m->nULR,m->nULC say chr(218)         color &cShadColor.
  4647.          @m->nBRR,m->nULC say chr(192)         color &cShadColor.
  4648.          @m->nULR,m->nBRC to m->nBRR,m->nBRC   color &cHighColor.
  4649.          @m->nBRR,m->nULC+1 to m->nBRR,m->nBRC color &cHighColor.
  4650.          @m->nULR,m->nBRC say chr(191)         color &cHighColor.
  4651.          @m->nBRR,m->nBRC say chr(217)         color &cHighColor.
  4652.       
  4653.          *-- inside of "border"
  4654.          @m->nULR+1,m->nULC+2 to m->nULR+1,m->nBRC-2 color &cHighColor. 
  4655.          @m->nULR+1,m->nULC+2 to m->nBRR-1,m->nULC+2 color &cHighColor. 
  4656.          @m->nULR+1,m->nULC+2 say chr(218)           color &cHighColor. 
  4657.          @m->nBRR-1,m->nULC+2 say chr(192)           color &cHighColor. 
  4658.          @m->nULR+1,m->nBRC-2 to m->nBRR-1,m->nBRC-2 color &cShadColor. 
  4659.          @m->nBRR-1,m->nULC+3 to m->nBRR-1,m->nBRC-2 color &cShadColor. 
  4660.          @m->nULR+1,m->nBRC-2 say chr(191)           color &cShadColor. 
  4661.          @m->nBRR-1,m->nBRC-2 say chr(217)           color &cShadColor. 
  4662.    
  4663.       case m->nStyle = 3
  4664.          
  4665.          *-- Raised SINGLE Border
  4666.          @m->nULR,m->nULC to m->nULR,m->nBRC color &cHighColor. 
  4667.          @m->nULR,m->nULC to m->nBRR,m->nULC color &cHighColor. 
  4668.          @m->nULR,m->nBRC to m->nBRR,m->nBRC color &cShadColor. 
  4669.          @m->nBRR,m->nULC to m->nBRR,m->nBRC color &cShadColor. 
  4670.          @m->nULR,m->nULC say chr(218)       color &cHighColor. 
  4671.          @m->nBRR,m->nULC say chr(192)       color &cHighColor. 
  4672.          @m->nULR,m->nBRC say chr(191)       color &cShadColor. 
  4673.          @m->nBRR,m->nBRC say chr(217)       color &cShadColor. 
  4674.          
  4675.       case m->nStyle = 4
  4676.    
  4677.          *-- Recessed SINGLE Border
  4678.          @m->nULR,m->nULC to m->nULR,m->nBRC color &cShadColor. 
  4679.          @m->nULR,m->nULC to m->nBRR,m->nULC color &cShadColor. 
  4680.          @m->nULR,m->nBRC to m->nBRR,m->nBRC color &cHighColor. 
  4681.          @m->nBRR,m->nULC to m->nBRR,m->nBRC color &cHighColor. 
  4682.          @m->nULR,m->nULC say chr(218)       color &cShadColor. 
  4683.          @m->nBRR,m->nULC say chr(192)       color &cShadColor. 
  4684.          @m->nULR,m->nBRC say chr(191)       color &cHighColor. 
  4685.          @m->nBRR,m->nBRC say chr(217)       color &cHighColor. 
  4686.    
  4687.    endcase
  4688.    
  4689.    *-- reset border
  4690.    set border to &cBorder.
  4691.    
  4692. RETURN
  4693. *-- EoP: Bord3D5
  4694.  
  4695. FUNCTION Bevel
  4696. *-----------------------------------------------------------------------
  4697. *-- Programmer..: Adam L. Menkes (Borland)
  4698. *-- Date........: 04/xx/1993
  4699. *-- Notes.......: Taken from the April/May issue of dTech News.
  4700. *--               This routine will create a 'beveled' area on the 
  4701. *--               screen (3-d border). This is done by passing two 
  4702. *--               parameters, and using the @/SAY for the starting 
  4703. *--               coordinates. This defaults to the Borland "chiseled
  4704. *--               steel" look. If you want other colors, you will need
  4705. *--               to modify this routine (or use a different one, such
  4706. *--               as BORD3D or BORD3D2 in DIALOGS.PRG).
  4707. *--               Quoting from the article:
  4708. *--                 "Placing text in the screen should be done before 
  4709. *--               the function is called. This way, the background color
  4710. *--               can blend in, though the text colors will become 
  4711. *--               black. If you do not want the text to display in black
  4712. *--               but still want it to blend, determine the dull color 
  4713. *--               color (which is the value of cClrBack in the program)
  4714. *--               and @...SAY the text with <your color>/<dull color>. 
  4715. *--               See the [code] for getting colors, and use the code 
  4716. *--               for getting cClrBack. For example, if your colors are
  4717. *--               "W+/B", the background color will be "W" ("+" is 
  4718. *--               stripped). Assuming this was stored to the variable 
  4719. *--               cBackColor and you wanted red text, the syntax would
  4720. *--               look like:
  4721. *--                       @ 5, 5 say bevel(10,60)
  4722. *--                       @10,27 say "Hello World" COLOR R/&cBackColor.
  4723. *--                 "Another feature of the UDF is the shadowing. The 
  4724. *--               shadowing effect is evened out by using 1/2 height 
  4725. *--               shadowing on the horizontal surface and the upper 
  4726. *--               right hand corner. This gives it a more natural 
  4727. *--               appearance than trying to even out the aspect ratio 
  4728. *--               by using full height shadowing for the bottom,
  4729. *--               and double for the right edge. This will not work 
  4730. *--               properly if you shade the entire background with a 
  4731. *--               character (chr(178) as an example."
  4732. *-- Written for.: dBASE IV, 2.0 
  4733. *-- Rev. History: 04/xx/1993 -- Original
  4734. *-- Calls.......: None
  4735. *-- Called by...: Any
  4736. *-- Usage.......: @<x>,<y> say Bevel(<nBottom>,<nRight>)
  4737. *-- Example.....: @5,10 say bevel(10,60)
  4738. *-- Returns.....: nul
  4739. *-- Parameters..: nBottom = bottom row
  4740. *--               nRight  = right column
  4741. *-----------------------------------------------------------------------
  4742.  
  4743.    parameters nBottom, nRight
  4744.    private nTop, nLeft, nBottom, nRight, cAttr, cBorder, ;
  4745.            cNormFore, cEnh, cClrFore, cClrBack, cClrShad
  4746.    
  4747.    m->nTop    = row()
  4748.    m->nLeft   = col()
  4749.    m->nBottom = iif(pcount() < 1, max(25,val(right(set("DISPLAY"),;
  4750.                    2))) - 2, m->nBottom+m->nTop)  && maximum:lastrow - 1
  4751.    m->nRight   = iif(pcount() < 2, 78, m->nLeft+m->nRight) && maximum 78
  4752.    
  4753.    *-- get current color settings for highlighting-- note use of 2.0
  4754.    *-- third parm for AT()
  4755.    m->cAttr     = set("ATTRIBUTES")
  4756. *   cEnh      = substr( m->cAttr, at(",",m->cAttr)+1,;
  4757. *                      at(",",m->cAttr,2)-1-at(",",m->cAttr))
  4758.    m->cNormBack = substr(m->cAttr,at("/",m->cAttr)+1,;
  4759.                      at(",",m->cAttr)-1-at("/",m->cAttr))
  4760.    m->cClrFore  = left(m->cAttr,at("/",m->cAttr)-1)
  4761.    m->cClrFore  = m->cClrFore+iif("+"$m->cClrFore,"","+")
  4762.    m->cClrFore  = iif(m->cClrFore = "N+","W+",m->cClrFore)
  4763.    m->cClrBack  = left(m->cClrFore,len(m->cClrFore) - ;
  4764.                        iif(right(m->cClrFore,1) = "+",1,0))
  4765.    m->cClrShad  = "N"
  4766.    m->cBorder =  set("BORDER")
  4767.    
  4768.    *-- fill region with color
  4769.    @m->nTop, m->nLeft -1 fill to m->nBottom, m->nRight color /&cClrBack.
  4770.    
  4771.    *-- draw shadow
  4772.    @m->nTop+1,m->nRight+1 fill to m->nBottom,m->nRight+1 ;
  4773.                                                    color /&cClrShad.
  4774.    @m->nTop,m->nRight+1 say chr(220)     color &cClrShad./&cNormBack.
  4775.    @m->nBottom+1,m->nLeft+1 say replicate(chr(223),;
  4776.                  m->nRight-m->nLeft+1)   color &cClrShad./&cNormBack.
  4777.    
  4778.    *-- Draw outer lines and highlights
  4779.    @m->nTop+1,m->nLeft    to m->nBottom - 1,m->nLeft    ;
  4780.                                            color &cClrFore./&cClrBack.
  4781.    @m->nBottom,m->nLeft+1 to m->nBottom,m->nRight - 1  ;
  4782.                                            color &cClrShad./&cClrBack.
  4783.    @m->nTop,m->nLeft+1    to m->nTop,m->nRight - 1  ;
  4784.                                            color &cClrFore./&cClrBack.
  4785.    @m->nTop+1,m->nRight   to m->nBottom-1,m->nRight ;
  4786.                                             color &cClrShad./&cClrBack.
  4787.    
  4788.    *-- Draw inner lines and highlights
  4789.    @m->nTop+2,m->nLeft+2    to m->nBottom-2,m->nLeft+2 ;
  4790.                                             color &cClrShad./&cClrBack.
  4791.    @m->nBottom-1,m->nLeft+3 to m->nBottom-1,m->nRight-3;
  4792.                                             color &cClrFore./&cClrBack.
  4793.    @m->nTop+1,m->nLeft+3    to m->nTop+1,m->nRight-3 ;
  4794.                                             color &cClrShad./&cClrBack.
  4795.    @m->nTop+2,m->nRight-2   to m->nBottom-2,m->nRight-2 ;
  4796.                                             color &cClrFore./&cClrBack.
  4797.    
  4798.    *-- Draw outer corners
  4799.    @m->nTop,m->nLeft     say chr(218)     color &cClrFore./&cClrBack.
  4800.    @m->nBottom,m->nLeft  say chr(192)     color &cClrFore./&cClrBack.
  4801.    @m->nTop,m->nRight    say chr(191)     color &cClrShad./&cClrBack.
  4802.    @m->nBottom,m->nRight say chr(217)     color &cClrShad./&cClrBack.
  4803.    
  4804.    *-- Draw inner corners
  4805.    @m->nTop+1,m->nLeft+2     say chr(218) color &cClrShad./&cClrBack.
  4806.    @m->nBottom-1,m->nLeft+2  say chr(192) color &cClrShad./&cClrBack.
  4807.    @m->nTop+1,m->nRight-2    say chr(191) color &cClrFore./&cClrBack.
  4808.    @m->nBottom-1,m->nRight-2 say chr(217) color &cClrFore./&cClrBack.
  4809.    
  4810.    *-- cleanup
  4811.    set border to &cBorder.
  4812.  
  4813. RETURN ""
  4814. *-- EoF: Bevel()
  4815.  
  4816. *-----------------------------------------------------------------------
  4817. *-- COLOR and other routines needed by those above
  4818. *-----------------------------------------------------------------------
  4819.  
  4820. PROCEDURE Shadow
  4821. *-----------------------------------------------------------------------
  4822. *-- Programmer..: Ashton-Tate
  4823. *-- Date........: 01/27/1992
  4824. *-- Notes.......: Creates a shadow for a window (taken from the dBASE IV
  4825. *--               picklist functions)
  4826. *-- Written for.: dBASE IV, 1.1
  4827. *-- Rev. History: 05/23/1991 - original procedure.
  4828. *--               12/14/1991 - Modified by Jim Magnant (TXAGGIE) - to 
  4829. *--               check for columns exceeding 79, and temporarily change
  4830. *--               last col. value (so routine doesn't "blow up").
  4831. *--               01/27/1992 -- Modified by Ken Mayer to check for 
  4832. *--               bottom of screen, based on what Jim did above. 
  4833. *--               No further than 23.
  4834. *--               06/02/1993 -- Modified to handle screens larger than 
  4835. *--               24 lines.
  4836. *-- Calls.......: None
  4837. *-- Called by...: Too many to list ...
  4838. *-- Usage.......: do shadow with <nULRow>,<nULCol>,<m->nBRRow>,<nBRCol>
  4839. *-- Example.....: save screen to sMain
  4840. *--               activate screen
  4841. *--               define window wError from 5,15 to 15,65 double color;
  4842. *--                    rg+/r,rg+/r,rg+/r
  4843. *--               do shadow with 5,15,15,65
  4844. *--               activate window WError
  4845. *--                && perform actions in window
  4846. *--               deactivate window WError
  4847. *--               release window WError
  4848. *--               restore screen from sMain
  4849. *--               release screen sMain
  4850. *-- Returns.....: None
  4851. *-- Parameters..: nULRow = Upper Left Row position
  4852. *--               nULCol = Upper Left Column position (x,y)
  4853. *--               nBRRow = Bottom Right Row position
  4854. *--               nBRCol = Bottom Right Column position (x2,y2)
  4855. *-----------------------------------------------------------------------
  4856.  
  4857.    parameters nULRow,nULCol,nBRRow,nBRCOL
  4858.    private nTempRow,nTempCol,nIncRow,nIncCol
  4859.  
  4860.    *-- if screen is larger than 24 lines (EGA43, EGA50 ...)
  4861.    m->cScreen = set("DISPLAY")
  4862.    if m->cScreen = "MONO"
  4863.       m->nScreen = 23
  4864.    else
  4865.       m->nScreen = val(right(m->cScreen,2))-2
  4866.    endif
  4867.       
  4868.    m->nTempRow = iif(m->nBRRow+1>m->nScreen,m->nScreen,m->nBRRow+1)
  4869.    m->nTempCol = iif(m->nBRCol+2>79,79,m->nBRCol+2)
  4870.    m->nIncRow = 1
  4871.    m->nIncCol = (m->nBRCol-m->nULCol) / (m->nBRRow-m->nULRow)
  4872.    do while m->nTempRow <> m->nULRow .or. m->nTempCol <> m->nULCol+2
  4873.       m->nRightCol = m->nBRCol
  4874.       m->nBRCol = iif(m->nBRCol + 2 > 79,77,m->nBRCol)
  4875.       m->nBotRow = m->nBRRow
  4876.       m->nBRRow = iif(m->nBRRow + 1 > m->nScreen,m->nScreen-1,m->nBRRow)
  4877.       @ m->nTempRow,m->nTempCol fill to m->nBRRow+1,m->nBRCol+2 ;
  4878.                                                     color n+/n
  4879.       m->nBRCol = m->nRightCol
  4880.       m->nBRRow = m->nBotRow
  4881.       m->nTempRow = iif(m->nTempRow<>m->nULRow,m->nTempRow - ;
  4882.                                            m->nIncRow,m->nTempRow)
  4883.       m->nTempCol = iif(m->nTempCol<>m->nULCol+2,m->nTempCol - ;
  4884.                                            m->nIncCol,m->nTempCol)
  4885.       m->nTempCol = iif(m->nTempCol<m->nULCol+2,m->nULCol+2,m->nTempCol)
  4886.    enddo
  4887.    
  4888. RETURN
  4889. *-- EoP: Shadow
  4890.  
  4891. PROCEDURE SMultPick
  4892. *-----------------------------------------------------------------------
  4893. *-- Programmer..: Jay Parsons (CIS: 72662,1305)
  4894. *-- Date........: 01/16/1993
  4895. *-- Notes.......: Does screen display loop for Multipick procedure.
  4896. *-- Written for.: dBASE IV, 1.5
  4897. *-- Rev. History: Original function 01/16/1993.
  4898. *-- Calls.......: None
  4899. *-- Called by...: Multipick
  4900. *-- Usage.......: DO SMultpick
  4901. *-- Parameters..: None, but procedure uses various variables set by the
  4902. *--               parent Multipick procedure.
  4903. *-----------------------------------------------------------------------
  4904.  
  4905.    private nThisOff, nThisRow, nThisElem, nHiRow, nR
  4906.    m->nThisOff = 0
  4907.    m->nR = min( m->nRo, m->nElems - m->nTop + 1 )
  4908.    do while m->nThisOff < m->nRo
  4909.       m->ThisRow = m->nDown + m->nThisOff
  4910.       m->ThisElem = m->nTop + m->nThisOff
  4911.       if m->nThisoff < m->nR
  4912.          if m->ThisElem = m->nHigh
  4913.             @ m->ThisRow, m->m->nRight say m->cBoxL + ;
  4914.               iif( &cArray.[ m->ThisElem, 2], ;
  4915.               m->cChar, " " ) + m->cBoxR color &cHigh.
  4916.             @ m->ThisRow, col() say left( &cArray.[ m->ThisElem, 1 ] ;
  4917.               + space( m->nLength ), m->nLength ) color &cHigh.
  4918.               nHiRow = m->ThisRow
  4919.          else
  4920.             @ m->ThisRow, m->nRight say m->cBoxL + ;
  4921.               iif( &cArray.[ m->ThisElem, 2], ;
  4922.               m->cChar, " " ) + m->cBoxR color &cNorm.
  4923.             @ m->ThisRow, col() say left( &cArray.[ m->ThisElem, 1 ] ;
  4924.               + space( m->nLength ), m->nLength ) color &cNorm.
  4925.          endif
  4926.       else
  4927.          @ m->ThisRow, m->nRight say space( m->nCkCol + len( m->cBoxR );
  4928.            + m->nLength )
  4929.       endif
  4930.       m->nThisoff = m->nThisOff + 1
  4931.    enddo
  4932.    @ m->nLast, m->nLPad say " Done " color &cQuit.
  4933.    @ m->nLast, m->nRPad say "Cancel" color &cQuit.
  4934.    @ m->nHiRow, m->nCkCol say ""
  4935.  
  4936. RETURN
  4937. *-- EoP: SMultPick
  4938.  
  4939. FUNCTION YesQuit
  4940. *-----------------------------------------------------------------------
  4941. *-- Programmer..: Jay Parsons  (CIS: 72662,1302)
  4942. *-- Date........: 02/24/1993
  4943. *-- Notes.......: Asks whether to quit and cancel changes; does so if 
  4944. *--               yes.
  4945. *-- Written for.: dBASE IV, Version 1.5.
  4946. *-- Rev. History: 02/.24/1993 -- Original Release
  4947. *-- Calls.......: YnMouse()            Function in SCREENS.PRG
  4948. *-- Called by...: Multipick
  4949. *-- Usage.......: YesQuit()
  4950. *-- Example.....: ? Yesquit()
  4951. *-- Parameters..: None
  4952. *-- Returns.....: Logical, .T. for "Yes" or .F. for "No"
  4953. *-- Side effects: If "Yes", restores cArray[ , 2 ] values from cTemp
  4954. *-----------------------------------------------------------------------
  4955.  
  4956.    private nX, lRet
  4957.  
  4958.    m->lRet = YnMouse( "","Do you wish to restore", ;
  4959.                "the original selection","and leave this routine?" )
  4960.    if m->lRet
  4961.       m->nX = 1
  4962.       do while m->nX <= m->nElems
  4963.          store cTemp[m->nX] to &cArray.[ m->nX, 2 ] 
  4964.          m->nX = m->nX + 1
  4965.       enddo
  4966.    endif
  4967.  
  4968. RETURN m->lRet
  4969. *-- EoF: YesQuit()
  4970.  
  4971. FUNCTION YnMouse
  4972. *-----------------------------------------------------------------------
  4973. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  4974. *-- Date........: 02/28/1993
  4975. *-- Notes.......: Returns .T. or .F. answer to question without leaving
  4976. *--               mouse droppings.  Will not respond to left arrow 
  4977. *--               properly unless set( "ESCAPE" ) is off.
  4978. *--               *******************************
  4979. *--               **** REQUIRES MUSCLICK.BIN ****
  4980. *--               *******************************
  4981. *-- Written for.: dBASE IV, Version 1.5.
  4982. *-- Rev. History: 02/23/93 - original function
  4983. *--               02/28/93 - revised to support right and left arrows
  4984. *-- Calls.......: HighColors()          Function in COLOR.PRG
  4985. *--               Center                Procedure in PROC.PRG ( if 
  4986. *--                                     centering )
  4987. *-- Called by...: Any
  4988. *-- Usage.......: YnMouse( <cColors>, <cP1> [, <cP2>...] [,<lYes>] )
  4989. *-- Example.....: ? YnMouse( "", "Are you sure?" )
  4990. *-- Parameters..: cColors   -   String, either blank or holding desired
  4991. *--                             colors as standard [ , enhanced [, 
  4992. *--                             border ] ]
  4993. *--               cP<n>     -   One or more strings of prompt 
  4994. *--                             characters.
  4995. *--                             < only 7 may be passed as literals using
  4996. *--                             dBASE IV 1.5 >.  They will be printed
  4997. *--                             one below the other.  There may not in
  4998. *--                             any event be more than the number of
  4999. *--                             useable screen rows less 6; the 
  5000. *--                             parameters line will have to be changed
  5001. *--                             to use more than 20. As furnished, the 
  5002. *--                             justification of the prompt strings is 
  5003. *--                             flush left.  To center them, see the 
  5004. *--                             commented lines in the code.
  5005. *--                             Centering uses the Center procedure in 
  5006. *--                             PROC.PRG.
  5007. *--               lYes      -   A logical .T. if the default answer is 
  5008. *--                             "Yes". This must be the last parameter, 
  5009. *--                             but it may follow any number of prompt 
  5010. *--                             lines.
  5011. *-- Returns.....: Logical, .T. for "Yes" or .F. for "No"
  5012. *-----------------------------------------------------------------------
  5013.  
  5014.    parameters cColors, cP01, cP02, cP03, cP04, cP05, cP06, cP07, cP08,;
  5015.              cP09, cP10, cP11, cP12, cP13, cP14, cP15, cP16, cP17, ;
  5016.              cP18, cP19, cP20, lYes
  5017.  
  5018.    private cYn, nX, lY, nParams, nRows, nCols, cWhich, nBot, nTop, nLeft
  5019.    private cColrs, cPads, nLPad, nRpad, lRet, nScr
  5020.  
  5021.    * obtain number of prompts, and default answer if provided
  5022.    m->nParams = pcount() - 1
  5023.    m->lY = .F.
  5024.    * if we have 22 parameters, last must be the default answer
  5025.    if m->nParams = 21
  5026.       m->lY = m->lYes
  5027.    * otherwise look at the last parameter's type--if it is logical
  5028.    * that's the default answer and not a prompt
  5029.    else
  5030.       m->cWhich = "cP" + right( str( 100 + m->nParams ), 2 )
  5031.       if type( m->cWhich ) = "L"
  5032.          m->lY = &cWhich.
  5033.          m->nParams = m->nParams - 1
  5034.       endif
  5035.    endif
  5036.  
  5037.    * we need six rows for top and bottom borders, space before prompts,
  5038.    * space after prompts, yes/no pads and space after them
  5039.    m->nRows = m->nParams + 6
  5040.    m->nScr = iif( "43" $ set( "DISPLAY" ), 43, 25 )
  5041.  
  5042.    * don't overwrite messages, status or scoreboard
  5043.    m->nBot = m->nScr - 2
  5044.    m->nTop = 0
  5045.    if set( "STATUS" ) = "ON"
  5046.       m->nBot = m->nBot - 2
  5047.    else
  5048.       if set( "SCOREBOARD" ) = "ON"
  5049.          m->nTop = 1
  5050.       endif
  5051.    endif
  5052.    if m->nRows > m->nBot - m->nTop
  5053.       activate screen
  5054.       ? "Too many prompt lines for screen size - aborting"
  5055.       wait
  5056.       cancel
  5057.    endif
  5058.  
  5059.    * find longest prompt line and window width it requires including
  5060.    * a space at both ends
  5061.    m->nX = 1
  5062.    m->nCols = 13               && 11 spaces for the pads, 2 for border
  5063.    do while m->nX <= m->nParams
  5064.       m->cWhich = "cP" + right( str( 100 + m->nX ), 2 )
  5065.       m->nCols = max( m->nCols, len( trim( &cWhich. ) ) + 2 )
  5066.       m->nX = m->nX + 1
  5067.    enddo
  5068.  
  5069.    * round up to even number of columns in order to center the window
  5070.    m->nCols = 2 * ceiling( m->nCols/ 2 )
  5071.    if m->nCols > 80
  5072.       activate screen
  5073.       ? "Prompts are too long for screen - aborting"
  5074.       wait
  5075.       cancel
  5076.    endif
  5077.  
  5078.    * calculate screen row of top and bottom of centered window
  5079.    m->nTop = max( m->nTop, int( ( m->nScr - m->nRows ) / 2 ) )
  5080.    m->nBot = m->nTop + m->nRows
  5081.  
  5082.  
  5083.    * and screen column of left edge
  5084.    m->nLeft = 39 - m->nCols / 2
  5085.  
  5086.    * obtain colors to use, using highlight for pads
  5087.    m->cColrs = iif( "" # m->cColors, m->cColors, set( "ATTRIBUTES" ) )
  5088.    if "&" $ m->cColrs
  5089.       m->cColrs = left( m->cColrs, at( "&", m->cColrs ) - 1  )
  5090.    endif
  5091.    m->cPads = HighColors( m->cColrs )
  5092.  
  5093.    * calculate column positions of yes/no pads
  5094.    m->nLPad = int( ( m->nCols - 2 ) / 4 ) - 2
  5095.    m->nRPad = m->nCols - m->nLPad - 6
  5096.  
  5097.    * now open the window and print prompts
  5098.    define window cYn from m->nTop, m->nLeft to m->nBot, ;
  5099.                          m->nLeft + m->nCols color &cColrs.
  5100.    activate window cYn
  5101.    m->nX = 1
  5102.    do while m->nX <= m->nParams
  5103.       m->cWhich = "cP" + right( str( 100 + m->nX ), 2 )
  5104.       *  To change from flush left to centered justification of the 
  5105.       *  prompts, uncomment the next code line and comment out the one
  5106.       *  following.
  5107.       *  You will then need the "Center" procedure in PROC.PRG.
  5108.       *         do Center with m->nX, m->nCols, "", &cWhich.
  5109.       @ m->nX, 1 say &cWhich.
  5110.       m->nX = m->nX + 1
  5111.    enddo
  5112.  
  5113.    * print pads
  5114.    @ m->nX + 1, m->nLPad say " Yes " color &cPads.
  5115.    @ m->nX + 1, m->nRPad say "  No " color &cPads.
  5116.    @ m->nX + 1, iif( m->lY, m->nLPad, m->nRPad ) + 2 say ""
  5117.  
  5118.    * and begin a loop that may last forever
  5119.    clear typeahead
  5120.    do while .T.
  5121.       m->nk = inkey()
  5122.       if m->nk = 0
  5123.          loop
  5124.       endif
  5125.       do case
  5126.          case m->nk = 89 .or. m->nk = 121    && 'Y' or 'y'
  5127.             m->lRet = .T.
  5128.             exit
  5129.           case m->nK = 78 .or. m->nK = 110 .or. m->nK = 27   
  5130.                                              && 'N' or 'n' or Esc
  5131.             m->lRet = .F.
  5132.             exit
  5133.          case m->nK = 13 .or. m->nK = 23     && Enter or Ctrl-End
  5134.             m->lRet = m->lY
  5135.             exit
  5136.          case m->nK = 4 .or. m->nK = 19      && right or left arrow
  5137.             m->lY = .not. m->lY
  5138.             @ m->nX + 1, iif( m->lY, m->nLPad, m->nRPad ) + 2 say ""
  5139.          case type( "nG_MusClic" ) = "N" .and. m->nk = m->nG_MusClic
  5140.             store chr(255) to m->cMRow, m->cMCol
  5141.             call MUSCLICK with m->cMRow, m->cMCol
  5142.             m->nMRow = asc( m->cMRow )
  5143.             m->nMCol = asc( m->cMCol )
  5144.            if m->nMRow = m->nTop + m->nX + 2      && one more for border
  5145.              if m->nMCol >= m->nLPad + m->nLeft .and. ;
  5146.                 m->nMCol < m->nLPad + m->nLeft + 5
  5147.                 m->lRet = .T.
  5148.                 exit
  5149.              endif
  5150.              if m->nMCol >= m->nRPad + m->nLeft .and. ;
  5151.                 m->nMCol <m->nRPad + m->nLeft + 5
  5152.                 m->lRet = .F.
  5153.                 exit
  5154.              endif
  5155.            endif
  5156.       endcase
  5157.    enddo
  5158.    deactivate window cYn
  5159.    release window cYn
  5160.  
  5161. RETURN m->lRet
  5162. *-- EoF: YnMouse()
  5163.  
  5164. FUNCTION CWnDecode
  5165. *-----------------------------------------------------------------------
  5166. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  5167. *-- Date........: 02/06/1993
  5168. *-- Notes.......: Returns the numeric value of one of the four codes for
  5169. *--               edges of the window held in a string of the type 
  5170. *--               returned by cWnSize.  These represent numbers of rows 
  5171. *--               or columns.
  5172. *-- Written for.: dBASE IV, Versions 1.0 - 1.5.
  5173. *-- Rev. History: 02/06/1993 -- Original Release
  5174. *-- Calls.......: None
  5175. *-- Called by...: Any
  5176. *-- Usage.......: cWnDecode( <cWnString>,<cEdge>|<nPos> )
  5177. *-- Example.....: cWim->nTop = cWnDecode( cWin, "T" )
  5178. *-- Parameters..: cWnString -   A string returned by CWnSize
  5179. *--               cEdge -       A character parameter beginning with one
  5180. *--                             of the four characters "T","L","B",or 
  5181. *--                             "R", ( upper or lower case ), OR
  5182. *--               nPos  -       A number indicating the position in the
  5183. *--                             cWnString of the code for the edge.
  5184. *--                             These correspond to the following:
  5185. *--                             Window edge       cEdge       nPos
  5186. *--                               top              T           1
  5187. *--                               left             L           2
  5188. *--                               bottom           B           3
  5189. *--                               right            R           4
  5190. *--                             Either cEdge or nPos must be furnished,
  5191. *--                             not both.
  5192. *-- Returns.....: numeric value of the row or column; -1 for argument
  5193. *--               out of range or cWnString holds garbage or is empty.
  5194. *-----------------------------------------------------------------------
  5195.  
  5196.    parameters cWnString, xEdge
  5197.    private nPos, nRet
  5198.  
  5199.    m->nRet = -1
  5200.    if type( "xEdge" ) = "C"
  5201.       m->nPos = at( upper( left( m->xEdge, 1 ) ), "TLBR" )
  5202.    else
  5203.       if type( "xEdge" ) = "N"
  5204.          m->nPos = m->xEdge
  5205.       endif
  5206.    endif
  5207.    if m->nPos > 0 .and. m->nPos < 5 .and. len( m->cWnString ) = 4
  5208.       m->nRet = asc( substr( m->cWnString, m->nPos, 1 ) ) - 1
  5209.    endif
  5210.    if m->nRet > iif( mod( m->nPos, 2 ) > 0, 43, 80 )
  5211.       m->nRet = -1
  5212.    endif
  5213.  
  5214. RETURN m->nRet
  5215. *-- EoF: CWnDecode
  5216.  
  5217. FUNCTION CWnSize
  5218. *-----------------------------------------------------------------------
  5219. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  5220. *-- Date........: 02/06/1993
  5221. *-- Notes.......: Returns a string of four characters which are chr()
  5222. *--               values of one more each than the top, left, bottom
  5223. *--               and right row and column numbers of the usable surface
  5224. *--               of the current window, or of the screen.  ( one more
  5225. *--               to avoid chr( 0 ) problems )
  5226. *--               Returns "" if unable to find VDCURSOR.BIN
  5227. *--               *******************************
  5228. *--               **** REQUIRES VDCURSOR.BIN ****
  5229. *--               *******************************
  5230. *-- Written for.: dBASE IV, Versions 1.0 - 1.5.
  5231. *-- Rev. History: 02/06/1993 -- Original Release
  5232. *-- Calls.......: nWBsrch()           function included
  5233. *-- Called by...: Any
  5234. *-- Usage.......: cWnSize()
  5235. *-- Example.....: cWin = cWnSize()
  5236. *--               WinBot = asc( substr( cWin, 3 1 ) )
  5237. *-- Parameters..: None
  5238. *-- Returns.....: character string of four chr() values, or "" if error
  5239. *-- Side effects: Called function nWBsrch disables any error trap
  5240. *-----------------------------------------------------------------------
  5241.  
  5242.    private nHi, nLo, nL, cV
  5243.  
  5244.    m->cV = ""
  5245.    if file( "VDCURSOR.BIN" )
  5246.       load VDCURSOR
  5247.       @ 0,0 say ""
  5248.       m->cV = call( "VDCURSOR","  " )
  5249.       release module VDCURSOR
  5250.       * reverse bytes so row comes first
  5251.       m->cV = right( m->cV, 1 ) + left( m->cV, 1 )
  5252.       * this is the first row, and one more than maximum last
  5253.       m->nL = asc( m->cV ) - 1
  5254.       m->nLo = m->nL
  5255.       m->nHi = 44
  5256.       m->cV = m->cV + chr( m->nL + nWBsrch( m->nLo, m->nHi, "Down" );
  5257.               + 1 )
  5258.       * first column and one more than last
  5259.       m->nL = asc( substr( m->cV, 2, 1 ) ) - 1
  5260.       m->nLo = m->nL
  5261.       m->nHi = 80
  5262.       m->cV = m->cV + chr( m->nL + nWBsrch( m->nLo, m->nHi, "Across" );
  5263.               + 1 )
  5264.    endif
  5265.  
  5266. RETURN m->cV
  5267. *-- EoF: CWnSize()
  5268.  
  5269. FUNCTION nWBsrch
  5270. *-----------------------------------------------------------------------
  5271. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  5272. *-- Date........: 02/06/1993
  5273. *-- Notes.......: special binary search routine for window edges
  5274. *-- Written for.: dBASE IV, Versions 1.0 - 1.5.
  5275. *-- Rev. History: 02/06/1993 -- Original Release
  5276. *-- Calls.......: None
  5277. *-- Called by...: cWnSize
  5278. *-- Usage.......: nWBsrch( < nLo >, < nHi >, < cDir > )
  5279. *-- Example.....: Lastrow = nWBsrch( 0, 44, "Down" )
  5280. *-- Parameters..: nLo           Number, top row or left column
  5281. *--               nHi           Number, bottom or right screen edge + 1
  5282. *--               cDir          char, direction - "Down" or "Across"
  5283. *-- Returns.....: number of highest row or column that may be written to
  5284. *-- Side effects: Disables any ON ERROR trap
  5285. *-----------------------------------------------------------------------
  5286.  
  5287.    parameters nLo, nHi, cDir
  5288.    private lToohigh, nTry, cD
  5289.  
  5290.    m->cD = upper( left( m->cDir, 1 ) )
  5291.    do while m->nHi > m->nLo + 1
  5292.       m->lTooHigh = .F.
  5293.       nTry = int( ( m->nHi + m->nLo ) / 2 )
  5294.       on error m->lTooHigh = .T.
  5295.       if m->cD $ "DB"
  5296.          @ nTry, 0 say ""
  5297.       else
  5298.          @ 0, nTry say ""
  5299.       endif
  5300.       if m->lTooHigh
  5301.          m->nHi = nTry - 1
  5302.       else
  5303.          m->nLo = nTry
  5304.       endif
  5305.    enddo
  5306.    on error
  5307.  
  5308. RETURN m->nLo
  5309. *-- EoF(): nWBsrch
  5310.  
  5311. FUNCTION ColorBrk
  5312. *-----------------------------------------------------------------------
  5313. *-- Programmer..: Ken Mayer (CIS: 71333,1030)
  5314. *-- Date........: 03/24/1993
  5315. *-- Notes.......: This routine is designed to be used with any of my 
  5316. *--               functions and procedures that accept a memory variable
  5317. *--               for color, and use a window. It's purpose is to break 
  5318. *--               that color var into it's components (depending on 
  5319. *--               which one the user wants) and return those components,
  5320. *--               so that they can then be used in SET COLOR OF ... 
  5321. *--               commands.
  5322. *-- Written for.: dBASE IV, 1.1, 1.5 (written because of 1.5, but will 
  5323. *--               work in 1.1)
  5324. *-- Rev. History: 07/22/1992 - modified to handle memvars/color strings
  5325. *--               that may have only two parts to them (no <border>...),
  5326. *--               so that if the <nField> parm is 2, we get a valid 
  5327. *--               value.
  5328. *--               03/24/1993 -- Lee Hite - Fixed to work correctly when 
  5329. *--               <cColorVar> contains a single colorset (i.e., "b/w").
  5330. *-- Calls.......: None
  5331. *-- Called by...: Any
  5332. *-- Usage.......: ColorBrk(<cColorVar>,<nField>)
  5333. *-- Example.....: set color of normal to ColorBrk(cColor,1)
  5334. *-- Returns.....: Either the field you asked for (1 thru 3) or null 
  5335. *--               string ("").
  5336. *-- Parameters..: cColorVar = Color variable to extract data from
  5337. *--                   Assumes the form: <main color>,<highlight>,;
  5338. *--                                     <border>
  5339. *--                   Where each part uses: <foreground>/<background>
  5340. *--                                          format
  5341. *--                    i.e., rg+/gb,w+/b,rg+/gb
  5342. *--               nField    = Field you want to extract
  5343. *-----------------------------------------------------------------------
  5344.  
  5345.    parameters cColorVar, nField
  5346.    private cReturn, cExtract
  5347.    
  5348.    do case
  5349.       case m->nField = 1
  5350.          if at(",",m->cColorVar) > 0
  5351.             m->cReturn = left(m->cColorVar,at(",",m->cColorVar)-1)
  5352.          else
  5353.             m->cReturn = m->cColorVar
  5354.          endif
  5355.       case m->nField = 2
  5356.          m->cExtract = substr(m->cColorVar,at(",",m->cColorVar)+1)  
  5357.                           && everything to right of comma
  5358.          if at(",",m->cExtract) > 0
  5359.             m->cReturn = left(m->cExtract,at(",",m->cExtract)-1)    
  5360.                           && left of second ,
  5361.          else
  5362.             m->cReturn = m->cExtract
  5363.          endif
  5364.       case m->nField = 3
  5365.          m->cExtract = substr(m->cColorVar,at(",",m->cColorVar)+1)
  5366.          if at(",",m->cExtract) > 0
  5367.             m->cReturn = substr(m->cExtract,at(",",m->cExtract)+1)
  5368.          else
  5369.             m->cReturn = ""
  5370.          endif
  5371.       otherwise
  5372.          m->cReturn = ""
  5373.    endcase
  5374.  
  5375. RETURN m->cReturn
  5376. *-- EoF: ColorBrk()
  5377.  
  5378. FUNCTION FBClrBrk
  5379. *-----------------------------------------------------------------------
  5380. *-- Programmer..: Joey D. Carroll (JOEY on USSBBS)
  5381. *-- Date........: 11/12/1992
  5382. *-- Notes.......: Extracts foreground/background colors from a string in
  5383. *--               the form of a literal "n/gb" or of a variable.  It is 
  5384. *--               useful to use COLORBRK() to obtain this value.
  5385. *-- Written for.: dBASE IV, ver 1.5
  5386. *-- Rev. History: 11/12/1992 -- Original
  5387. *-- Calls.......: None
  5388. *-- Called by...: Any
  5389. *-- Usage.......: ?? FBClrBrk("B","w+/gr")
  5390. *-- Example.....: cNormalClr = "w+/gr"
  5391. *--               cForeClr   = FBClrBrk("F",cNormalClr)   && = "w+"
  5392. *--               cBackClr   = FBClrBrk("B",cNormalClr)   && = "gr"
  5393. *-- Returns.....: a sub-string of cColor
  5394. *-- Parameters..: cType  = "F" for foreground color  "B" for Background
  5395. *--               cColor = the color you want to extract from
  5396. *-----------------------------------------------------------------------
  5397.  
  5398.    parameters cType,cColor
  5399.    private cRetClr
  5400.  
  5401.    if upper(cType) = "F"
  5402.       m->cRetClr = iif(at("/",m->cColor) = 0,m->cColor,;
  5403.                    left(m->cColor,at("/",m->cColor)-1))
  5404.    else           && = "B"
  5405.       m->cRetClr = substr(m->cColor,at("/",m->cColor) + 1,2)
  5406.    endif
  5407.  
  5408. RETURN m->cRetClr
  5409. *-- EoF: FBClrBrk()
  5410.  
  5411. FUNCTION BackColor
  5412. *-----------------------------------------------------------------------
  5413. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  5414. *-- Date........: 02/24/1993
  5415. *-- Notes.......: Returns background part of color string.
  5416. *-- Written for.: dBASE IV, Version 1.5.
  5417. *-- Rev. History: 02/04/1993 -- Original Release
  5418. *-- Calls.......: None
  5419. *-- Called by...: Any
  5420. *-- Usage.......: BackColor( <cColor> )
  5421. *-- Example.....: ? BackColor( "N/BG" )
  5422. *-- Parameters..: cColor    -   String holding color foreground and 
  5423. *--                             background
  5424. *-- Returns.....: Character, string with background portion of the color
  5425. *--               Returns empty string if no such portion.
  5426. *-----------------------------------------------------------------------
  5427.  
  5428.    parameters cColor
  5429.    private cRet
  5430.  
  5431.    m->cRet = upper( trim( ltrim( m->cColor ) ) )
  5432.    if "/" $ m->cRet
  5433.       m->cRet = substr( m->cRet, at( "/", m->cRet ) + 1 )
  5434.       if "*" $ m->cRet
  5435.          m->cRet = stuff( m->cRet, at( "*", m->cRet ), 1, "" )
  5436.       endif
  5437.       if "+" $ m->cRet 
  5438.          m->cRet = stuff( m->cRet, at( "+", m->cRet ), 1, "" )
  5439.       endif
  5440.    else
  5441.       m->cRet = ""
  5442.    endif
  5443.  
  5444. RETURN upper( ltrim( trim( m->cRet ) ) )
  5445. *-- EoF: BackColor()
  5446.  
  5447. FUNCTION NormColors
  5448. *-----------------------------------------------------------------------
  5449. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  5450. *-- Date........: 02/23/1993
  5451. *-- Notes.......: Returns the "normal" portion of a color string
  5452. *-- Written for.: dBASE IV, Version 1.5.
  5453. *-- Rev. History: 02/23/1993 -- Original Release
  5454. *-- Calls.......: None
  5455. *-- Called by...: Any
  5456. *-- Usage.......: NormColors( <cColor> )
  5457. *-- Example.....: ? NormColors( "N/BG,BG+/N,W+/B" )
  5458. *-- Parameters..: cColor    -   String holding colors
  5459. *-- Returns.....: Character, normal color portion of string.
  5460. *-----------------------------------------------------------------------
  5461.  
  5462.    parameters cColor
  5463.    private cRet
  5464.  
  5465.    m->cRet = m->cColor
  5466.    if "," $ m->cRet
  5467.       m->cRet = left( m->cRet, at( ",", m->cRet ) - 1 )
  5468.    endif
  5469.  
  5470. RETURN upper( ltrim( trim ( m->cRet ) ) )
  5471. *-- EoF: NormColors()
  5472.  
  5473. FUNCTION HighColors
  5474. *-----------------------------------------------------------------------
  5475. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  5476. *-- Date........: 02/23/1993
  5477. *-- Notes.......: Returns the "highlight" portion of a color string
  5478. *-- Written for.: dBASE IV, Version 1.5.
  5479. *-- Rev. History: 02/23/1993 -- Original Release
  5480. *-- Calls.......: None
  5481. *-- Called by...: Any
  5482. *-- Usage.......: HighColors( <cColor> )
  5483. *-- Example.....: ? HighColors( "N/BG,BG+/N,W+/B" )
  5484. *-- Parameters..: cColor    -   String holding colors
  5485. *-- Returns.....: Character, highlight color portion of string.
  5486. *--               Returns empty string if no such portion.
  5487. *-----------------------------------------------------------------------
  5488.  
  5489.    parameters cColor
  5490.    private cRet
  5491.  
  5492.    m->cRet = ""
  5493.    if "," $ m->cColor
  5494.       m->cRet = substr( m->cColor, at( ",",m->cColor ) + 1 )
  5495.       if "," $ m->cRet
  5496.          m->cRet = left( m->cRet, at( ",", m->cRet ) - 1 )
  5497.       endif
  5498.    endif
  5499.  
  5500. RETURN upper( ltrim( trim( m->cRet ) ) )
  5501. *-- EoF: HighColors()
  5502.  
  5503. FUNCTION ForeColor
  5504. *-----------------------------------------------------------------------
  5505. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  5506. *-- Date........: 02/24/1993
  5507. *-- Notes.......: Returns foreground part of color string.
  5508. *-- Written for.: dBASE IV, Version 1.5.
  5509. *-- Rev. History: 02/24/1993 -- Original Release
  5510. *-- Calls.......: None
  5511. *-- Called by...: Any
  5512. *-- Usage.......: ForeColor( <cColor> )
  5513. *-- Example.....: ? ForeColor( "N/BG" )
  5514. *-- Parameters..: cColor    -   String holding color foreground and 
  5515. *--                             background
  5516. *-- Returns.....: Character, string with foreground portion of the color
  5517. *-----------------------------------------------------------------------
  5518.  
  5519.    parameters cColor
  5520.    private cRet
  5521.  
  5522.    m->cRet = upper( trim( ltrim( m->cColor ) ) )
  5523.    if "/" $ m->cRet
  5524.       m->cRet = left( m->cRet, at( "/", m->cRet ) - 1 )
  5525.    endif
  5526.    if "*" $ m->cColor
  5527.       m->cRet = m->cRet + "*"
  5528.    endif
  5529.    if "+" $ m->cColor
  5530.       m->cRet = m->cRet + "+"
  5531.    endif
  5532.  
  5533. RETURN m->cRet
  5534. *-- EoF: ForeColor()
  5535.  
  5536. PROCEDURE ReColor
  5537. *-----------------------------------------------------------------------
  5538. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  5539. *-- Date........: 04/23/1992
  5540. *-- Notes.......: Restores colors to those held in a string of the form
  5541. *--               returned by set("ATTRIBUTE").
  5542. *-- Written for.: dBASE IV, Versions 1.0 - 1.5.
  5543. *-- Rev. History: 04/23/1992 -- Original Release
  5544. *-- Calls.......: None
  5545. *-- Called by...: Any
  5546. *-- Usage.......: DO ReColor WITH <cColors>
  5547. *-- Example.....: DO Recolor WITH OldColors
  5548. *-- Parameters..: cColors = a string in the form returned by 
  5549. *--                         set("ATTRIBUTE").
  5550. *-- Returns.....: None
  5551. *-- Side effects: Changes the screen colors.
  5552. *-----------------------------------------------------------------------
  5553.  
  5554.    parameters cColors
  5555.    private cThis, cNext, nAt, cLeft, nX, cAreas
  5556.  
  5557.    m->cAreas = "   NORMHIGHBORDMESSTITLBOX INFOFIEL"
  5558.    m->cLeft = m->cColors + ", "
  5559.    m->nX = 0
  5560.    do while m->nX < 8
  5561.       m->nX = m->nX + 1
  5562.       cThis = substr( m->cAreas, 4 * m->nX, 4 )
  5563.       if m->nX = 3
  5564.          m->nAt = at( "&", m->cLeft )
  5565.          m->cNext = left( m->cLeft, m->nAt - 2 )
  5566.          m->cLeft = substr( m->cLeft, m->nAt + 3 )
  5567.          SET COLOR TO , , &cNext.
  5568.       else
  5569.          m->nAt = at( ",", m->cLeft )
  5570.          m->cNext = left( m->cLeft, m->nAt - 1 )
  5571.          m->cLeft = substr( m->cLeft, m->nAt + 1 )
  5572.          SET COLOR OF &cThis TO &cNext.
  5573.       endif
  5574.    enddo
  5575.  
  5576. RETURN
  5577. *-- EoP: ReColor
  5578.  
  5579. PROCEDURE WordWrap
  5580. *-----------------------------------------------------------------------
  5581. *-- Programmer..: David Frankenbach (CIS: 72147,2635)
  5582. *-- Date........: 01/14/1993 (Version 1.1)
  5583. *-- Notes.......: Wraps a long string, breaking it into strings that 
  5584. *--               have a maximum length of nWidth. The first output is 
  5585. *--               displayed @nRow, nCol. Words are not split ...
  5586. *-- Written for.: dBASE IV, 1.5
  5587. *-- Rev. History: 01/06/1993 -- Original Release (Version 1.0)
  5588. *--               01/14/1993 -- Version 1.1 -- Corrected side-effect of 
  5589. *--                       destroying string arg, added test for 
  5590. *--                       string[nWidth+1] = " "
  5591. *-- Calls.......: None
  5592. *-- Called by...: Any
  5593. *-- Usage.......: do WordWrap with <nRow>, <nCol>, <cString>, <nWidth>
  5594. *-- Example.....: do WordWrap with 2,2,cText,38
  5595. *-- Returns.....: None
  5596. *-- Parameters..: nRow     = Row to display first line at
  5597. *--               nCol     = Left side of area to display text at
  5598. *--               cString  = text to wrap
  5599. *--               nWidth   = Width of area to wrap text in
  5600. *-----------------------------------------------------------------------
  5601.  
  5602.    parameters nRow, nCol, cString, nWidth
  5603.    private cTemp, nI, cStr
  5604.    
  5605.    m->cStr = m->cString           && work with a COPY of input, to avoid
  5606.                                   && destroying original
  5607.    
  5608.    do while len(m->cStr) > 0      && while there's something to work on
  5609.       if (m->nWidth < len(m->cStr))
  5610.          m->nI = m->nWidth        && look for last " " in first nWidth
  5611.          
  5612.          if substr(m->cStr,m->nI+1,1) # " "
  5613.             do while ((m->nI > 0) .and. (substr(m->cStr,m->nI,1) # " "))
  5614.                m->nI = m->nI - 1
  5615.             enddo
  5616.          endif
  5617.          
  5618.          if m->nI = 0              && no spaces
  5619.             m->nI = m->nWidth      && get first nWidth characters
  5620.          endif
  5621.       else
  5622.          m->nI = len(m->cStr)      && use the rest of the string
  5623.       endif
  5624.       
  5625.       cTemp = left(m->cStr,m->nI) && get the part we're going to display
  5626.       
  5627.       if m->nI < len(m->cStr)         && remove that part
  5628.          m->cStr = ltrim(substr(m->cStr,m->nI + 1))
  5629.       else
  5630.          m->cStr = ""
  5631.       endif
  5632.       
  5633.       *-- display it
  5634.       @m->nRow,m->nCol say m->cTemp
  5635.  
  5636.       *-- move to next row
  5637.       m->nRow = m->nRow + 1
  5638.       
  5639.    enddo
  5640.    
  5641. RETURN
  5642. *-- EoP: WordWrap
  5643.  
  5644. PROCEDURE Center
  5645. *-----------------------------------------------------------------------
  5646. *-- Programmer..: Miriam Liskin
  5647. *-- Date........: 05/24/1991
  5648. *-- Notes.......: Centers text on the screen with @says
  5649. *-- Written for.: dBASE IV, 1.1
  5650. *-- Rev. History: This and all other procedures/functions listed in this
  5651. *--               file attributed to Miriam Liskin came from "Liskin's
  5652. *--               Programming dBASE IV Book". Very good, worth the money
  5653. *-- Calls.......: None
  5654. *-- Called by...: Any
  5655. *-- Usage.......: do center with <nLine>,<nWidth>,"<cColor>","<cText>"
  5656. *-- Example.....: do center with 5,65,"RG+/GB",;
  5657. *--                                   "WARNING! This will blow up!"
  5658. *--                  Note that the color field may be blank: ""
  5659. *-- Returns.....: None
  5660. *-- Parameters..: nLine  = Line or Row for @/Say
  5661. *--               nWidth = Width of screen
  5662. *--               cColor = Colors to be used ("Forg/Back") (may be nul
  5663. *--                        "", in order to use the default colors of 
  5664. *--                        window/screen)
  5665. *--               cText  = Message to center on screen
  5666. *-----------------------------------------------------------------------
  5667.    
  5668.    parameters nLine,nWidth,cColor,cText
  5669.    private nCol
  5670.    
  5671.    m->nCol = (m->nWidth - len(m->cText)) /2
  5672.    @m->nLine,m->nCol say m->cText color &cColor.
  5673.    
  5674. RETURN
  5675. *-- EoP: Center
  5676.  
  5677. FUNCTION AllTrim
  5678. *-----------------------------------------------------------------------
  5679. *-- Programmer..: Phil Steele (from PCSDEMO.PRG -- Public Domain)
  5680. *-- Date........: 05/23/1991
  5681. *-- Notes.......: Complete trims edges of field (left and right)
  5682. *-- Written for.: dBASE IV, 1.1
  5683. *-- Rev. History: 05/23/1991 -- Original
  5684. *-- Calls.......: None
  5685. *-- Called by...: Any
  5686. *-- Usage.......: alltrim(<cString>)
  5687. *-- Example.....: ? alltrim("  Test String  ") 
  5688. *-- Returns.....: Trimmed string, i.e.:"Test String"
  5689. *-- Parameters..: cString = string to be trimmed
  5690. *-----------------------------------------------------------------------
  5691.    
  5692.    parameters cString
  5693.    
  5694. RETURN ltrim(rtrim(m->cString))
  5695. *-- EoF: AllTrim()
  5696.  
  5697. FUNCTION Justify
  5698. *-----------------------------------------------------------------------
  5699. *-- Programmer..: Roland Bouchereau (Ashton-Tate/Borland)
  5700. *-- Date........: 03/24/1993
  5701. *-- Notes.......: Used to pad a field/string on the right, left or both,
  5702. *--               justifying or centering it within the length 
  5703. *--               specified. If the length of the string passed is 
  5704. *--               greater than the size needed, the function will 
  5705. *--               truncate it. Taken from Technotes, June 1990. 
  5706. *--               Defaults to Left Justify if invalid TYPE is passed ...
  5707. *-- Written for.: dBASE IV, 1.0
  5708. *-- Rev. History: Original function 06/15/1991
  5709. *--               12/17/1991 -- Modified into ONE function from three by
  5710. *--                  Ken Mayer, added a third parameter to handle that.
  5711. *--               12/23/1992 -- Modified by Joey Carroll to use STUFF()
  5712. *--                  instead of TRANSFORM().
  5713. *--               03/24/1993 -- Modified by Lee Hite, as the center
  5714. *--                  option wasn't working quite right ...
  5715. *-- Calls.......: None
  5716. *-- Called by...: Any
  5717. *-- Usage.......: Justify(<cFld>,<nLength>,"<cType>")
  5718. *-- Example.....: ?? Justify(Address,25,"R")
  5719. *-- Returns.....: Padded/truncated field
  5720. *-- Parameters..: cFld    =  Field/Memvar/Character String to justify
  5721. *--               nLength =  Width to justify within
  5722. *--               cType   =  Type of justification: L=Left, C=Center,
  5723. *--                          R=Right
  5724. *-----------------------------------------------------------------------
  5725.    
  5726.    parameters cFld,nLength,cType
  5727.    private cReturn
  5728.    
  5729.    m->cType = upper(m->cType)    && just making sure ...
  5730.    if type("cFld")+type("nLength")+type("cType") $ "CNC,CFC"
  5731.       *-- set a picture function of 'X's, with @I,@J or @B function
  5732.       m->cReturn = space(m->nLength)
  5733.       m->cReturn = stuff(m->cReturn,;
  5734.             iif(m->cType = "C",((m->nLength-len(m->cFld))/2)+1,;
  5735.             iif(m->cType = "R",m->nLength-len(m->cFld)+1,1)),;
  5736.             len(m->cFld),m->cFld)
  5737.    else
  5738.       m->cReturn = ""
  5739.    endif
  5740.  
  5741. RETURN m->cReturn
  5742. *-- EoF: Justify()
  5743.  
  5744. FUNCTION ArrayRows
  5745. *-----------------------------------------------------------------------
  5746. *-- Programmer..: Jay Parsons (CIS: 72662,1302)
  5747. *-- Date........: 03/01/1992
  5748. *-- Notes.......: Number of Rows in an array
  5749. *-- Written for.: dBASE IV, 1.1
  5750. *-- Rev. History: 03/01/1992 -- Original Release
  5751. *-- Calls.......: None
  5752. *-- Called by...: Any
  5753. *-- Usage.......: ArrayRows("<aArray>")
  5754. *-- Example.....: n = ArrayRows("aTest")
  5755. *-- Returns.....: numeric
  5756. *-- Parameters..: aArray      = Name of array 
  5757. *-----------------------------------------------------------------------
  5758.  
  5759.    parameters aArray
  5760.    private nHi, nLo, nTrial, nDims
  5761.  
  5762.    m->nLo = 1
  5763.    m->nHi = 1170
  5764.    if type( "&aArray[ 1, 1 ]" ) = "U"
  5765.       m->nDims = 1
  5766.    else
  5767.      m->nDims = 2
  5768.    endif
  5769.    do while .T.
  5770.      m->nTrial = int( ( m->nHi + m->nLo ) / 2 )
  5771.      if m->nHi < m->nLo
  5772.         exit
  5773.      endif
  5774.      if m->nDims = 1 .and. type( "&aArray.[ m->nTrial ]" ) = "U" .or. ;
  5775.         m->nDims = 2 .and. type( "&aArray.[ m->nTrial, 1 ]" ) = "U"
  5776.         m->nHi = m->nTrial - 1
  5777.      else
  5778.         m->nLo = m->nTrial + 1
  5779.      endif
  5780.    enddo
  5781.    
  5782. RETURN m->nTrial
  5783. *-- EoF: ArrayRows()
  5784.  
  5785. *-----------------------------------------------------------------------
  5786. *-- End of Program: DIALOGS.PRG
  5787. *-----------------------------------------------------------------------
  5788.